gpt4 book ai didi

r - 在data.table中聚合时如何查看多个 `by`中逗号分隔字符串背后的逻辑?

转载 作者:行者123 更新时间:2023-12-05 02:03:18 27 4
gpt4 key购买 nike

data.table 中,我们可以执行以下操作来聚合数据:

as.data.table(dat)[, sum(x), by='g,d']
# g d V1
# 1: a 1 1.69036285
# 2: a 2 -3.17443208
# 3: a 3 -1.25045813
# 4: a 4 -0.54787167
# 5: b 1 0.88889824
# 6: b 2 -2.09544124
# 7: b 3 -0.98484236
# 8: b 4 1.43268901
# 9: c 1 4.79890459
# 10: c 2 -0.76440764
# 11: c 3 -1.18732658
# 12: c 4 0.08166043
# 13: d 1 -2.66427903
# 14: d 2 -0.30073505
# 15: d 3 0.09255934
# 16: d 4 4.18462582

但是,当在函数中使用预定义参数时,从所有尝试来看

as.data.table(dat)[, sum(x), by=paste("g", "d", sep=",")]
# Error in `[.data.table`(as.data.table(dat), , sum(x), by = paste(c("g", :
# 'by' appears to evaluate to column names but isn't c() or key(). Use by=list(...)
# if you can. Otherwise, by=eval(paste(c("g", "d"), collapse = ",")) should work.
# This is for efficiency so data.table can detect which columns are needed.

as.data.table(dat)[, sum(x), by=paste(c("g", "d"), collapse=",")]
# Error in `[.data.table`(as.data.table(dat), , sum(x), by = paste("g", : ...

bys <- c("g", "d")
as.data.table(dat)[, sum(x), by=paste(bys, collapse=",")]
# Error in `[.data.table`(as.data.table(dat), , sum(x), by = paste("g", : ...

只有以下似乎有效:

bys <- paste("g", "d", sep=",")
as.data.table(dat)[, sum(x), by=bys]
# g d V1
# 1: a 1 1.69036285
# 2: a 2 -3.17443208
# 3: a 3 -1.25045813
# 4: a 4 -0.54787167
# 5: b 1 0.88889824
# 6: b 2 -2.09544124
# 7: b 3 -0.98484236
# 8: b 4 1.43268901
# 9: c 1 4.79890459
# 10: c 2 -0.76440764
# 11: c 3 -1.18732658
# 12: c 4 0.08166043
# 13: d 1 -2.66427903
# 14: d 2 -0.30073505
# 15: d 3 0.09255934
# 16: d 4 4.18462582

据我了解,差异应该无关紧要,不是吗?为什么会这样?


数据

set.seed(42)
dat <- transform(expand.grid(d=1:4, g=letters[1:4], g2=1:4), x=rnorm(64))

最佳答案

错误在 this line 上抛出在 data.table.R 中的 [.data.table 函数中. by 参数被非标准评估捕获;在你的情况下,发生在 this line 上使用 substitute .

by=bysub= if (missing(by)) NULL else substitute(by)

这使得示例的三个版本的计算方式不同,正如您在这个玩具示例中看到的那样:

f <- function(by) {
substitute(by)
}

bys <- paste("g", "d", sep = ",")

f(bys)
#> bys

f(paste("g", "d", sep = ","))
#> paste("g", "d", sep = ",")

f("g,d")
#> [1] "g,d"

这个 substitute 调用的结果存储为一个名为 bysub 的变量,它会非常仔细和彻底地检查它是否是字符、名称、表达式或一个电话。如果像您的情况一样,它是一个调用,则会检查正在调用哪个函数。只有某些函数调用被处理而没有错误,包括 evalc:key。对其他函数的调用将根据您问题中的错误进行处理。

这似乎是一个有意识的设计决策,旨在提高 [.data.table 函数的整体效率。由于这个函数超过 1700 行,我不得不承认我还没有探索这个设计的“原因”,但希望您至少可以了解“如何”。

关于r - 在data.table中聚合时如何查看多个 `by`中逗号分隔字符串背后的逻辑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65296380/

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