gpt4 book ai didi

data.table 中的递归赋值

转载 作者:行者123 更新时间:2023-12-04 11:10:34 25 4
gpt4 key购买 nike

是否可以在 data.table执行多列的递归分配?通过递归,我的意思是下一个分配取决于上一个分配:

library(data.table)
DT = data.table(id=rep(LETTERS[1:4], each=2), val=1:8)
DT[, c("cumsum", "cumsumofcumsum"):=list(cumsum(val), cumsum(cumsum)), by=id]

# Error in `[.data.table`(DT, , `:=`(c("cumsum", "cumsumofcumsum"), list(cumsum(val), :
# cannot coerce type 'builtin' to vector of type 'double'

当然,您可以单独进行分配,但我想开销成本(例如分组)不会在操作之间分摊:
DT = data.table(id=rep(LETTERS[1:4], each=2), val=1:8)
DT[, c("cumsum"):=cumsum(val), by=id]
DT[, c("cumsumofcumsum"):=cumsum(cumsum), by=id]
DT
# id val cumsum cumsumofcumsum
# 1: A 1 1 1
# 2: A 2 3 4
# 3: B 3 3 3
# 4: B 4 7 10
# 5: C 5 5 5
# 6: C 6 11 16
# 7: D 7 7 7
# 8: D 8 15 22

最佳答案

您可以使用临时变量并将其再次用于其他变量:

DT[, c("cumsum", "cumsumofcumsum"):={
x <- cumsum(val)
list(x, cumsum(x))
}, by=id]

当然你可以用 dplyr并使用您的 data.table 作为后端,但我不确定您是否会获得与纯 data.table 方法相同的性能:
library(dplyr)
DT %>%
group_by(id ) %>%
mutate(
cum1 = cumsum(val),
cum2 = cumsum(cum1)
)

编辑添加一些benchamrks:

纯 data.table 解决方案比 dplyr 解决方案快 5 倍。我想幕后 dplyr 中的排序可以解释这种差异。
f_dt <- 
function(){
DT[, c("cumsum", "cumsumofcumsum"):={
x <- as.numeric(cumsum(val))
list(x, cumsum(x))
}, by=id]
}

f_dplyr <-
function(){
DT %>%
group_by(id ) %>%
mutate(
cum1 = as.numeric(cumsum(val)),
cum2 = cumsum(cum1)
)
}


library(microbenchmark)

microbenchmark(f_dt(),f_dplyr(),times = 100)
expr min lq median uq max neval
f_dt() 2.580121 2.97114 3.256156 4.318658 13.49149 100
f_dplyr() 10.792662 14.09490 15.909856 19.593819 159.80626 100

关于data.table 中的递归赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26192236/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com