我只想了解函数rowSums的奇怪行为。想象一下,我有一个超级简单的数据框架:
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
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,则一切都正常:
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我是不是遗漏了什么?
感谢所有
发布于 2016-07-23 17:22:04
rowSums的一种选择是在将所有NAs转换为NA (NA^)后,根据NA值获得带有na.rm=TRUE的na.rm=TRUE,并与否定(!) rowSums的否定(!)逻辑矩阵相乘。
rowSums(df, na.rm=TRUE) *NA^!rowSums(!is.na(df))
#[1] 2 NA 10发布于 2016-07-23 17:03:28
因为
sum(numeric(0))
# 0在rowSums中使用rowSums之后,第二行是numeric(0)。取sum后,为0。
如果您想为所有的NA案例保留NA,这将是一个两阶段的工作。为此,我建议编写一个小函数:
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的“黑客”回答,我建议:
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 10https://stackoverflow.com/questions/38544325
复制相似问题