从data.table中的列中获取总数和净总数R
问题描述:
我想获取data.table中某个列的值的总值和净值之和。通过整笔款项,我的意思是忽略负值,因此,对于在这个例子中a
,净总和是4,总金额为5从data.table中的列中获取总数和净总数R
>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
但我真的不希望有一个额外的列添加到数据,因为有几百万行的,我可能要跨越多个列做到这一点。有没有办法直接做到这一点?我可以计算出如何得到总的总数或净总数(通过在i
中加上value > 0
得到总的总数),但是不能同时得到总数。
答
这是你在找什么?
dt[, .(netTotal = sum(value), grossTotal = sum(value * (value > 0))), by=id]
我一次计算两列。使用(value > 0)
作为逻辑删除sum
中的负值。
答
您是否熟悉dplyr软件包?如果没有,请检查一下,一旦你掌握了这些任务,这些任务就会变得非常简单。
library(dplyr)
dt %>% group_by(id) %>% summarize(net = sum(value), gross = sum(ifelse(value > 0, value, 0)))
答
我显然误解了这个请求,因为我还以为你也要求总计。因此,这里的是无偿的解决方案:
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
答
我们也可以子集,而不是通过逻辑指数乘以
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
是的,这也正是它。对R相对缺乏经验,并且不熟悉这个习语。谢谢。 –