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

dle*_*eal 8 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))
Run Code Online (Sandbox Code Playgroud)

这不添加参数na.rm = T,C组应返回4时返回NA。

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

但是,na.rm = T在A组应返回NA时,相加将返回0。

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

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

ifelse(all(is.na(col2)), NA, sum(col2, na.rm = T)
Run Code Online (Sandbox Code Playgroud)

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

sum.na <- function(df){

  if (all(is.na(df))){

    suma <- NA
  }  
  else {    
    suma <- sum(df, na.rm = T)
  }

  return(suma)
}
Run Code Online (Sandbox Code Playgroud)

dle*_*eal 6

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

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

1)使用 ifelse:

A[, (ifelse(all(is.na(col2)), col2[NA_integer_], sum(col2, na.rm = T))), 
  by = .(col1)]
Run Code Online (Sandbox Code Playgroud)

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

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

A[, suma(col2), by = .(col1)]
Run Code Online (Sandbox Code Playgroud)

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