首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RowSums NA + NA给出0

RowSums NA + NA给出0
EN

Stack Overflow用户
提问于 2016-07-23 17:01:11
回答 2查看 1.8K关注 0票数 0

我只想了解函数rowSums的奇怪行为。想象一下,我有一个超级简单的数据框架:

代码语言:javascript
复制
a = c(NA, NA,3)
b = c(2,NA,2)
df = data.frame(a,b)
df
   a  b
1 NA  2
2 NA NA
3  3  2

现在我想要第三列,也就是另外两列的和。我不能简单地使用+,因为NA

代码语言:javascript
复制
df$c <- df$a + df$b
df
   a  b  c
1 NA  2 NA
2 NA NA NA
3  3  2  5

但是,如果我使用rowSums,具有NA的行将被计算为0,而如果只有一个NA,则一切都正常:

代码语言:javascript
复制
df$d <- rowSums(df, na.rm=T)
df
   a  b  c  d
1 NA  2 NA  2
2 NA NA NA  0
3  3  2  5 10

我是不是遗漏了什么?

感谢所有

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-07-23 17:22:04

rowSums的一种选择是在将所有NAs转换为NA (NA^)后,根据NA值获得带有na.rm=TRUEna.rm=TRUE,并与否定(!) rowSums的否定(!)逻辑矩阵相乘。

代码语言:javascript
复制
rowSums(df, na.rm=TRUE) *NA^!rowSums(!is.na(df))
#[1]  2 NA 10
票数 6
EN

Stack Overflow用户

发布于 2016-07-23 17:03:28

因为

代码语言:javascript
复制
sum(numeric(0))
# 0

rowSums中使用rowSums之后,第二行是numeric(0)。取sum后,为0。

如果您想为所有的NA案例保留NA,这将是一个两阶段的工作。为此,我建议编写一个小函数:

代码语言:javascript
复制
my_rowSums <- function(x) {
  if (is.data.frame(x)) x <- as.matrix(x)
  z <- base::rowSums(x, na.rm = TRUE)
  z[!base::rowSums(!is.na(x))] <- NA
  z
  }

my_rowSums(df)
# [1]  2 NA 10

如果输入x是一个数据框架(就像在您的例子中那样),这可能特别有用。base::rowSums将首先检查输入是否为矩阵。如果它得到一个数据框架,它将首先将它转换为一个矩阵。实际上,类型转换比实际行和计算花费更大。请注意,我们两次调用base::rowSums。为了减少类型转换开销,我们应该确保x是一个矩阵。

关于@akrun的“黑客”回答,我建议:

代码语言:javascript
复制
akrun_rowSums <- function (x) {
  if (is.data.frame(x)) x <- as.matrix(x)
  rowSums(x, na.rm=TRUE) *NA^!rowSums(!is.na(x))
  }

akrun_rowSums(df)
# [1]  2 NA 10
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38544325

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档