2017-04-07 114 views
1

我有一个大的data.frame,其中有character列和几个包含NA的数字列。使用data.table与NAs汇总数据帧

这里有几个例子行:

df <- data.frame(id=rep("A",3),v1=c(NA,1,NA),v2=c(2,5,2),v3=c(NA,NA,NA),V4=c(0,0,0),stringsAsFactors=F) 

由于df$id重复我想aggregatedfdf$id,并申请sum所有其他列。

我这样做:

require(data.table) 
setDT(df)[,lapply(.SD, function(x) sum(x,na.rm=T)),by=.(id)] 

,并正在此:

id v1 v2 v3 V4 
1: A 1 9 0 0 

所以列v3df所有NA的,因此得到的0的值,这对一个问题因为在这种情况下,我想保持NA的价值,但在所有其他情况下(其中聚合是通过混合数字和NA的,显然我想删除否则总和将为NA)。如示例所示(df$v4),我的列全部为0,因此我不能简单地将0的全部替换为的NA

换句话说,这是我想要的结果:

id v1 v2 v3 V4 
1: A 1 9 NA 0 

任何想法如何获得data.table.SD聚集到实现这一目标?

+1

不是'data.table'问题:'总和(C(NA,NA,NA),na.rm = TRUE)'返回'0',因为*“空集合的总和为零,根据定义”。* – Cath

+2

编写自己的函数mySum < - 函数(x)if(all(is.na(x)))NA else sum x,na.rm = TRUE)' – jogo

回答

5
df[,lapply(.SD, function(x) ifelse(all(is.na(x)),NA,sum(x,na.rm=T))),by=.(id)] 
id v1 v2 v3 V4 
1: A 1 9 NA 0 
1

我们也可以这样做没有if/else声明

setDT(df)[, lapply(.SD, function(x) sum(x, na.rm = TRUE)*NA^all(is.na(x))), id] 
# id v1 v2 v3 V4 
#1: A 1 9 NA 0