我有一个包含数十万行的数据框,但可以在下面举例说明:
> mydata
ID TYPE HEIGHT WEIGHT
1 20 6 194 77.1
2 20 2 175 63.5
3 20 6 197 59.6
4 20 1 185 74.3
5 20 1 162 94.4
6 21 1 188 58.9
7 21 6 182 81.2
8 21 6 169 82.8
9 21 2 151 78.5
这是重现它的代码:
mydata <- data.frame(ID=c(20,20,20,20,20,21,21,21,21),
TYPE=(c(6,2,6,1,1,1,6,6,2)),
HEIGHT=c(194,175,197,185,162,188,182,169,151),
WEIGHT=c(77.1,63.5,59.6,74.3,94.4,58.9,81.2,82.8,78.5))
我需要做的是:对每个ID
,计算WEIGHTS
by的总和TYPE
,但仅对那些具有HEIGHT
高于当前行中所包含元素的元素(具有相同ID)进行计算。
然后,新的数据框应再包含三列(每列一列TYPE
),并最终应如下所示:
> mydata_new
ID TYPE HEIGHT WEIGHT SUM.W.TYPE6 SUM.W.TYPE2 SUM.W.TYPE1
1 20 6 194 77.1 59.6 0.0 0.0
2 20 2 175 63.5 136.7 0.0 74.3
3 20 6 197 59.6 0.0 0.0 0.0
4 20 1 185 74.3 136.7 0.0 0.0
5 20 1 162 94.4 136.7 63.5 74.3
6 21 1 188 58.9 0.0 0.0 0.0
7 21 6 182 81.2 0.0 0.0 58.9
8 21 6 169 82.8 81.2 0.0 59.9
9 21 2 151 78.5 164.0 0.0 58.9
如果可能的话,我想避免遍历每一行,因为给定我的大量数据集,这将花费很长时间。有什么聪明的解决方案吗?或许用一些合适的软件包,如dplyr
,data.table
或简单地使用apply
或sapply
?
我想了解如何基于同一行的不同列中的值创建一个累加和,但也取决于单独的分组(即TYPE
)。
如操作说明中所述,累积总和在这里起作用:
library(data.table)
setDT(mydata)
ut = sort(unique(mydata$TYPE))
mydata[order(-HEIGHT), paste0("sum_",ut) := lapply(ut,
function(x) shift(cumsum( WEIGHT*(TYPE==x) ), fill=0)
), by=ID]
ID TYPE HEIGHT WEIGHT sum_1 sum_2 sum_6
1: 20 6 194 77.1 0.0 0.0 59.6
2: 20 2 175 63.5 74.3 0.0 136.7
3: 20 6 197 59.6 0.0 0.0 0.0
4: 20 1 185 74.3 0.0 0.0 136.7
5: 20 1 162 94.4 74.3 63.5 136.7
6: 21 1 188 58.9 0.0 0.0 0.0
7: 21 6 182 81.2 58.9 0.0 0.0
8: 21 6 169 82.8 58.9 0.0 81.2
9: 21 2 151 78.5 58.9 0.0 164.0
重复高度测量。到目前为止,这仅在每个ID内的所有高度都不同的情况下才有效(如OP的当前示例)。但是,OP在评论中提到高度可能会重复。感谢@DeanMacGregor,这是该情况的扩展:
# run the code above, and then...
mydata[order(-HEIGHT), paste0('sum_',ut) :=
.SD[.N]
, by=.(ID,TYPE,HEIGHT), .SDcols=paste0('sum_',ut)]
或者by
一步来做:
ut = sort(unique(mydata$TYPE))
mydata[order(-HEIGHT), paste0("sum_",ut) := {
sd = lapply(ut, function(x) shift(cumsum( WEIGHT*(TYPE==x) ), fill=0))
setDT(sd)[, .SD[1L], by=.(HEIGHT,TYPE)][, c("HEIGHT","TYPE") := NULL]
}, by=ID]
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句