r语言 - 仅对非 NA 元素求和,但如果所有 NA 则返回 NA



我想我已经在评论中得到了非常好的答案,但我会改写这个问题以供将来参考。

我正在尝试使用data.table按组求和。问题是有些组只有 NA。对于这些组,我希望总和返回 NA。但是,如果有一个组有一个值与 NA 不同,我想获得非 NA 值的总和。

A <- data.table(col1= c('A','A','B','B','C','C'),  
                col2= c(NA,NA,2,3,NA,4))

这在不添加参数的情况下na.rm = T,组 C 在应该返回 4 时返回 NA。

A[, sum(col2), by = .(col1)]
   col1 V1
1:    A NA
2:    B  5
3:    C NA

但是,添加 na.rm = T 在组 A 中返回 0,而它应该返回 NA。

A[, sum(col2, na.rm = T), by = .(col1)]
   col1 V1
1:    A  0
2:    B  5
3:    C  4

我最喜欢的方法是Sandipan在评论中建议的方法,类似于我在下面写的功能:

ifelse(all(is.na(col2)), NA, sum(col2, na.rm = T)

我创建了一个函数来解决这个问题,但我不确定是否有一种内置的方法可以解决这个问题:

sum.na <- function(df){
  if (all(is.na(df))){
    suma <- NA
  }  
  else {    
    suma <- sum(df, na.rm = T)
  }
  return(suma)
}

根据其他用户的建议,我将发布我问题的答案。解决方案由@sandipan在上面的评论中提供:

如问题中所述,如果您需要对包含 NA 的一列的值求和,有两种好方法:

1) 使用 ifelse:

A[, (ifelse(all(is.na(col2)), col2[NA_integer_], sum(col2, na.rm = T))), 
  by = .(col1)]

2) 按照@Frank的建议定义一个函数:

suma = function(x) if (all(is.na(x))) x[NA_integer_] else sum(x, na.rm = TRUE)
A[, suma(col2), by = .(col1)]

请注意,正如@Frank指出的那样,我添加了NA_integer_,因为我不断收到有关类型的错误。

使用 sum_ from hablar

library(hablar)
A[, as.numeric(sum_(col2)), .(col1)]
#   col1 V1
#1:    A NA
#2:    B  5
#3:    C  4

最新更新