gpt4 book ai didi

r - data.table 分组操作,列的变量名没有慢 DT[, mean(get(colName)), by = grp]

转载 作者:行者123 更新时间:2023-12-04 14:47:41 25 4
gpt4 key购买 nike

我想创建一个使用列变量名和数据变量名的函数。
这个功能是我想要的,它的工作原理:

n <- 1e7
d <- data.table(x = 1:n, grp = sample(1:1e5, n, replace = T))
dataName = "d"
colName = "x"

# Objective :
FOO <- function(dataName = "d",
colName = "x"){
get(dataName)[, mean(get(colName)), by = grp]
}
问题是对 get()的评价每组都非常耗时。在真实数据示例中,它比静态名称等效项长 14 倍。我想达到与列名是静态的相同的执行时间。
我试过的:
(cl <- substitute(mean(eval(parse(text = colName))), list(colName = as.name(colName))))

microbenchmark::microbenchmark(

# 1) works and quick but does not use variable names of columns (654ms)
(t1 <- d[, mean(x), by = grp]),

# 2) works but slow (1006ms)
(t2 <- get(dataName)[, mean(get(colName)), by = grp]), # works but slow

# 3) works but slow (4075ms)
(t3 <- eval(parse(text = dataName))[, mean(eval(parse(text = colName))), by = grp]),

# 4) works but very slow (37202ms)
(t4 <- get(dataName)[, eval(cl), by = grp]),

# 5) double dot syntax doesn't work cause I don't master it
# (t5 <- get(dataName)[, mean(..colName), by = grp]),

times = 10)
双点语法在这里合适吗?为什么 4) 这么慢?我从 this post 拿的这是最好的选择。我从这个 post 改编了双点语法.
非常感谢你的帮助 !

最佳答案

最好将数据集名称 d 传递给 FOO 函数,而不是传递字符串 "d" 。此外,您可以将 lapply.SD 结合使用,以便您可以从内部优化中受益,而不是使用 mean(get(colName))

FOO2 = function(dataName=d, colName = "x") { # d instead of "d" passed to the first argument!
dataName[, lapply(.SD, mean), by=grp, .SDcols=colName]
}
基准: FOOFOO2
set.seed(147852)
n <- 1e7
d <- data.table(x = 1:n, grp = sample(1:1e5, n, replace = T))

microbenchmark::microbenchmark(
FOO(),
FOO2(),
times=5L
)

Unit: milliseconds
expr min lq mean median uq max neval
FOO() 4632.4014 4672.7781 4787.4958 4707.9023 4846.7081 5077.6893 5
FOO2() 255.0828 267.1322 297.0389 275.4467 281.9873 405.5456 5

关于r - data.table 分组操作,列的变量名没有慢 DT[, mean(get(colName)), by = grp],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69720385/

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