r - 将变量名作为参数传递给 data.table
问题描述
我正在尝试创建一个修改 data.table 的函数,并想使用一些非标准的评估,但我意识到我真的不知道如何在 data.tables 中使用它。我的功能基本上是这样的:
do_stuff <- function(dt, col) {
copy(dt)[, new_col := some_fun(col)][]
}
我想这样称呼它:
do_stuff(data, column)
其中“column”是“data”中存在的列的名称。如果我运行该函数,我会收到一个错误:
#> Error in some_fun(col) : object 'column' not found
这对我说 data.table 显然将正确的名称传递给函数(“列”),但由于某种原因它没有找到它。这是一个最小的可重现示例
library(data.table)
data <- data.table(x = 1:10, y = rnorm(10))
plus <- function(x, y) {
x + y
}
add_one <- function(data, col) {
copy(data)[, z := plus(col, 1)][]
}
add_one(data, y)
#> Error in plus(col, 1): object 'y' not found
不幸的是,使用deparse(substitute(col))
似乎不起作用:(
add_one <- function(data, col) {
copy(data)[, z := plus(deparse(substitute(col)), 1)][]
}
add_one(data, y)
#> Error in x + y: non-numeric argument to binary operator
解决方案
通常, quote 和 eval 将起作用:
library(data.table)
plus <- function(x, y) {
x + y
}
add_one <- function(data, col) {
expr0 = quote(copy(data)[, z := plus(col, 1)][])
expr = do.call(substitute, list(expr0, list(col = substitute(col))))
cat("Evaluated expression:\n"); print(expr); cat("\n")
eval(expr)
}
set.seed(1)
library(magrittr)
data.table(x = 1:10, y = rnorm(10)) %>%
add_one(y)
这使
Evaluated expression:
copy(data)[, `:=`(z, plus(y, 1))][]
x y z
1: 1 -0.6264538 0.3735462
2: 2 0.1836433 1.1836433
3: 3 -0.8356286 0.1643714
4: 4 1.5952808 2.5952808
5: 5 0.3295078 1.3295078
6: 6 -0.8204684 0.1795316
7: 7 0.4874291 1.4874291
8: 8 0.7383247 1.7383247
9: 9 0.5757814 1.5757814
10: 10 -0.3053884 0.6946116
推荐阅读
- python - 如何在数据框中设置字符串类型索引?
- python - python elasticsearch模块中create()方法的正确调用是什么?
- java - 我可以将 ObjectOutputStream 拆分为多个文件吗
- sql - 将 SQL 从一个表更新到另一个表
- sql-server - 选择一个预定义的最大值
- powershell - 基于日期时间的 Powershell AD 过滤
- google-apps-script - deleteRows 函数正在用 500 个空白行填充我的 Google 表格
- vuejs2 - 如何解决对 vuejs 挂载()/创建()事件的多次调用
- amazon-cloudfront - 避免限制机器人的 Cloudfront 地理限制
- rest - 如何在 kogito quarkus 中创建自定义的 Rest 端点