gpt4 book ai didi

r - 使用 data.table 分配多个相互引用的变量

转载 作者:行者123 更新时间:2023-12-01 13:43:42 26 4
gpt4 key购买 nike

我想为一个变量赋值,然后使用该变量创建一个新变量。 data.table 的语法支持多重赋值,但显然不支持内部引用。我实际用例中的“i”和“by”子句更复杂,所以我不希望像这样重复代码:

require(data.table)

dt <- data.table(
x = 1:5,
y = 2:6
)

# this works
dt[x == 3, z1 := x + y]
dt[x == 3, z2 := z1 + 5]

# but I wish this worked
dt[x == 3, `:=`(
z1 = x + y,
z2 = z1 + 5
)]

相比之下,这适用于 dplyr:
require(dplyr)

df <- data.frame(
x = 1:5,
y = 2:6
)

df <- mutate(df,
z1 = x + y,
z2 = z1 + 5
)

有没有一种干净的方法可以使用 data.table 来做到这一点?

编辑:
稍微调整 akrun 的解决方案,我想出了一种方法来保持我正在寻找的可读、顺序语法。它只是执行列表之外的所有操作:
dt[x==3, c('z1','z2','z3') := {
z1 <- x+y
z2 <- z1 + 5
z3 <- z2 + 6
list(z1, z2, z3)
}]

最佳答案

我们可以使用大括号创建临时变量,然后将它们放在 list 中。连同基于该变量的计算,将 ( := ) 分配给我们需要创建的列。

dt[x==3, c('z1', 'z2') := {
z1 <- x+y
list(z1, z1+5)
}]
dt
# x y z1 z2
#1: 1 2 NA NA
#2: 2 3 NA NA
#3: 3 4 7 12
#4: 4 5 NA NA
#5: 5 6 NA NA

为了让它更快一点,我们可以使用 setkey
setkey(dt, x)[(3),  c('z1', 'z2') := {
z1 <- x+y
list(z1, z1+5)
}]

基准
set.seed(24)
dt1 <- data.table(x = sample(1:9, 1e8, replace=TRUE), y = sample(5:9, 1e8, replace=TRUE))

dt2 <- copy(dt1)
dt3 <- copy(dt1)

akrun1 <- function(){dt1[x==3, c('z1', 'z2') := {
z1 <- x+y
list(z1, z1+5)
}]
}

akrun2 <- function() {setkey(dt3, x)[(3), c('z1', 'z2') := {
z1 <- x+y
list(z1, z1+5)
}]
}


rsoren <- function() {
dt2[x == 3, z1 := x + y]
dt2[x == 3, z2 := z1 + 5]
}



library(microbenchmark)
microbenchmark(akrun1(), akrun2(), rsoren(), unit= "relative", times = 20L)
#Unit: relative
# expr min lq mean median uq max neval
# akrun1() 1.597267 1.605404 1.393016 1.642584 1.538929 0.8634406 20
# akrun2() 1.000000 1.000000 1.000000 1.000000 1.000000 1.0000000 20
# rsoren() 2.584153 2.586185 2.179601 2.694469 2.468219 0.9740701 20

关于r - 使用 data.table 分配多个相互引用的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37626478/

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