r - data.table 中的 Computed `by` 子句
问题描述
by
子句可以是用于计算分组列的表达式列表。它也可以是一个表达式,计算结果为列名的字符向量,如果它包含在eval(…)
. 但是,如果您想以编程方式确定存在哪些分组变量以及存在多少个分组变量,并且并非所有这些分组变量都是预先存在的列,该怎么办?你会认为它是可行的eval
, quote
, 或bquote
我无法弄清楚。
作为一个简单但人为的示例,假设您要编写一个像这样工作的函数:
f = function(x)
{d = as.data.table(mtcars)
if (x)
d[, by = .(mycyl = cyl + 1, myv = vs + 1),
mean(wt)]
else
d[, by = .(mycyl = cyl + 1),
mean(wt)]}
但看起来像这样:
f = function(x)
{d = as.data.table(mtcars)
d[, by = c(.(mycyl = cyl + 1), (if (x) .(myv = vs + 1) else NULL)),
mean(wt)]}
这怎么可能实现?如所写,第二个版本产生Error in .(mycyl = cyl + 1) : could not find function "."
. 如果.
替换为list
,则生成Error in eval(bysub, parent.frame(), parent.frame()) : object 'cyl' not found
。
解决方案
你其实很亲近。使用list
代替.
library(data.table)
d = as.data.table(mtcars)
d[, mean(wt), by = .(mycyl = cyl + 1, myv = vs + 1),]
#> mycyl myv V1
#> 1: 7 1 2.755000
#> 2: 5 2 2.300300
#> 3: 7 2 3.388750
#> 4: 9 1 3.999214
#> 5: 5 1 2.140000
d[, mean(wt), by = .(mycyl = cyl + 1)]
#> mycyl V1
#> 1: 7 3.117143
#> 2: 5 2.285727
#> 3: 9 3.999214
x = FALSE
d[, mean(wt), by = if(x) list(mycyl = cyl + 1) else list(mycyl = cyl + 1, myv = vs + 1)]
#> mycyl myv V1
#> 1: 7 1 2.755000
#> 2: 5 2 2.300300
#> 3: 7 2 3.388750
#> 4: 9 1 3.999214
#> 5: 5 1 2.140000
x = TRUE
d[, mean(wt), by = if(x) list(mycyl = cyl + 1) else list(mycyl = cyl + 1, myv = vs + 1)]
#> mycyl V1
#> 1: 7 3.117143
#> 2: 5 2.285727
#> 3: 9 3.999214
推荐阅读
- wordpress - WordPress:通过过滤器自定义 Ajax 请求响应
- javascript - 使用 mqtt.js 时遇到内存泄漏问题
- python - 在 Numba 中关闭列表反射
- c++ - 嗨,我需要 C++ 图形方面的帮助。我被困住了
- ruby-on-rails - 根据 ruby on rails 中提供的输入在文本字段中填充数据
- c++ - QtCreator:部署单元测试
- go - 为什么正则表达式给我 golang 中的编译时恐慌错误?
- wordpress - 订购自定义 wordpress 循环
- bash - 如何在 bashrc 文件中为别名命令动态设置路径的一部分
- javascript - Highcharts - 在多个地方使用相同的图表