gpt4 book ai didi

r - data.table 错误 : lapply on . SD 在使用 get() 时对列重新排序。可能的解决方法?

转载 作者:行者123 更新时间:2023-12-03 18:17:43 24 4
gpt4 key购买 nike

我发现了 data.table 的奇怪行为.我想知道是否有办法避免它或解决方法。

在我的数据管理中,我经常使用 lapply.SD , 为列分配新值。要正确分配几列,lapply 的输出列的顺序必须保留。
我发现情况并非如此。

这里的正常行为

library(data.table)
plouf <- data.table(x = 1, y = 2, z = 3)
cols <- c("y","x")
plouf[,.SD,.SDcols = cols ,by = z]
plouf[,lapply(.SD,function(x){x}),.SDcols = cols ,by = z]
plouf[,lapply(.SD[x == 1],function(x){x}),.SDcols = cols ,by = z]

所有这些行给出:
   z y x
1: 3 2 1

例如,我需要将其重新分配给 c("y","x")。但如果我这样做:
plouf[,lapply(.SD[get("x") == 1],function(x){x}),.SDcols = c("y","x"),by = z]

z x y
1: 3 1 2

这里 x 和 y 的顺序无缘无故改变了,它应该产生与上一个“工作”示例相同的结果。如果然后将错误的值分配给 c("y","x")如果我分配 lapply 的输出到新的列向量。好像是用 geti .SD 的一部分触发此错误。

这对分配的影响示例:
plouf[, c(cols ) := lapply(.SD[get("x") == 1],function(x){x}),
.SDcols = cols ,by = z][]
# x y z
# 1: 2 1 3

有没有人有解决方法?我使用的代码看起来更像是:
 plouf[, c(cols ) := lapply(.SD[get("x") >= 1 & get("x") <= 3],function(x){mean}),
.SDcols = cols ,by = z]

github 上的问题: https://github.com/Rdatatable/data.table/issues/4089

最佳答案

而不是子集.SD ,您可以在 lapply 函数中进行子集化。如果用于子集的逻辑向量作为第三个参数传递给 lapply,则不会在每次 lapply 传递时重新评估。

注意:我将函数更改为乘以 10,否则我根本无法判断代码是否在执行任何操作

plouf[, (cols) := lapply(.SD, function(x, i) 10*mean(x[i]), 
get("x") %between% c(1, 3)),
.SDcols = cols ,by = z][]

# x y z
# 1: 10 20 3

还有其他解决方法可以让您对 .SD 进行子集化,但我认为子集化 .SD按组比单独对每一列进行子集化要慢。
set.seed(0)
df <- rep(1:50000, sample(500:1000, 50000, T)) %>%
data.table(a = runif(length(.))
,b = .)

library(microbenchmark)
microbenchmark(
subSD = df[, lapply(.SD[a < .2], sum), b]
, in_func = df[, lapply(.SD, function(x, i) sum(x[i]), a < .2), b]
, times = 10L)

# Unit: milliseconds
# expr min lq mean median uq max neval cld
# subSD 19323.19 20398.3666 21289.345 20708.4346 22466.010 23738.467 10 b
# in_func 972.64 987.7891 1016.252 995.4236 1038.069 1125.709 10 a

编辑:更大的基准
set.seed(0)
rm(df)
df <- rep(1:5e5, sample(50:100, 5e5, T)) %>%
data.table(a = runif(length(.))
,b = .)

library(microbenchmark)
microbenchmark(
subSD = df[, lapply(.SD[a < .2], sum), b]
, in_func = df[, lapply(.SD, function(x, i) sum(x[i]), a < .2), b]
, times = 2L)

# Unit: seconds
# expr min lq mean median uq max neval cld
# subSD 207.111290 207.111290 214.147649 214.147649 221.18401 221.18401 2 b
# in_func 3.560467 3.560467 3.651359 3.651359 3.74225 3.74225 2 a

关于r - data.table 错误 : lapply on . SD 在使用 get() 时对列重新排序。可能的解决方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59176071/

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