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

时间:2017-01-04 17:54:25

标签: r data.table

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

我试图使用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。

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

但是,添加na.rm = T时,如果应返回NA,则在A组中返回0。

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)
}

2 个答案:

答案 0 :(得分:3)

根据其他用户的建议,我会将答案发给我的问题。该解决方案由@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)]

请注意,我添加了NA_integer_作为@Frank指出,因为我一直收到有关类型的错误。

答案 1 :(得分:1)

使用sum_中的hablar

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