从R

时间:2016-05-23 16:19:41

标签: r data.table

我想获得data.table中某个列中值的总和和净值。总和,我的意思是忽略负值,因此在本例中,对于a,净额为4,总和为5。

>dt = data.table(id = c("a","a","a","b","b","b","b","c","c"),value = c(-1,2,3,-3,4,-2,3,-1,1))
>head(dt,3)
   id value
1:  a    -1
2:  a     2
3:  a     3 

我可以通过添加一个额外的列来实现,如下所示:

>dt$grossValue = dt$value
>dt$grossValue[dt$grossValue < 0] = 0
>dt[,.(netTotal = sum(value),grossTotal= sum(grossValue)),by=id]
   id netTotal grossTotal
1:  a        4          5
2:  b        2          7
3:  c        0          1

但我真的不想为数据添加额外的列,因为有数百万行,我可能希望跨多个列执行此操作。有没有办法直接这样做?我可以弄清楚如何获得总计或总计(通过在value > 0中添加i获得总计),但不能同时计算两者。

4 个答案:

答案 0 :(得分:4)

这是你在找什么?

dt[, .(netTotal = sum(value), grossTotal = sum(value * (value > 0))), by=id]

我在一次通过中计算了两列。 (value > 0)用作从sum中删除负值的逻辑。

答案 1 :(得分:1)

我显然误解了这个请求,因为我认为你也要求总计。所以这就是无偿的解决方案:

rbind( dt[,.(netTotal = sum(value),grossTotal= sum(value*(value>0))),by=id],
 data.table( id="all", netTotal=dt[,sum(value)], grossTotal=dt[,sum(value*(value>0))]))
#-------------
    id netTotal grossTotal
1:   a        4          5
2:   b        2          7
3:   c        0          1
4: all        6         13

答案 2 :(得分:0)

你熟悉dplyr包吗?如果没有,请查看它,一旦你掌握了它,它就会使这些任务变得非常简单。

library(dplyr)
dt %>% group_by(id) %>% summarize(net = sum(value), gross = sum(ifelse(value > 0, value, 0)))

答案 3 :(得分:0)

我们也可以通过逻辑索引

进行子集化而不是乘以
dt[, .(netTotal = sum(value), grossTotal = sum(value[value>0])) , id]
#   id netTotal grossTotal
#1:  a        4          5
#2:  b        2          7
#3:  c        0          1