这个问题就是数据.表相当于Pass a data.frame column name to a function.

假设我有一个非常简单的数据.表:

dat <- data.table(x = 1:4,
                  y = 5:8)

现在我想为任何给定函数创建一个新列:

new_column <- function(df,col_name,expr){
    col_name <- deparse(substitute(col_name))
    df[[col_name]] <- eval(substitute(expr),df,parent.frame())
    df
}

从而正确地提供:

> new_column (dat,z,x+y)
  x y  z
1 1 5  6
2 2 6  8
3 3 7 10
4 4 8 12

然而,因为这是一个数据.表I希望使用:=创建此新列:

new_column_byref <- function(df,col_name,expr){
   col_name <- deparse(substitute(col_name))
  df[, col_name:=eval(substitute(expr)
                      ,df
                      ,parent.frame()
                      )]
  df
}

但它不起作用:

> a <- new_column_byref(dat,z,x+y)
 Error: Check that is.data.table(DT) == TRUE. Otherwise, :=, `:=`(...) and let(...) are defined for use in j, once only and in particular ways. See help(":=").

我该怎么解决这个问题?非常感谢.

推荐答案

set是数据.餐桌习惯用语.如果你需要做其他事情,比如use byrlang有一种延迟计算的通用方法,那就是enexpr args(或者enquo,如果你想在原始环境中对它们进行计算),然后用你通常使用的表达式将它们放入inject中.

library(rlang)
#> Warning: package 'rlang' was built under R version 4.1.2
library(data.table)
#> 
#> Attaching package: 'data.table'
#> The following object is masked from 'package:rlang':
#> 
#>     :=

dat <- data.table(x = 1:4,
                  y = 5:8)

new_column <- function(df, col_name, expr) {
    col_name <- enexpr(col_name)
    expr <- enexpr(expr)
    inject(df[, !!col_name := !!expr])
}

new_column(dat, z, x + y)

dat
#>        x     y     z
#>    <int> <int> <int>
#> 1:     1     5     6
#> 2:     2     6     8
#> 3:     3     7    10
#> 4:     4     8    12

reprex package(v2.0.1)于2022年2月25日创建

或者,同样没有rlang

library(data.table)

dat <- data.table(x = 1:4,
                  y = 5:8)

new_column <- function(df, col_name, expr) {
    col_name <- deparse(substitute(col_name))
    expr <- substitute(expr)
    df[, (col_name) := eval(expr)]
}

new_column(dat, z, x + y)

dat
#>        x     y     z
#>    <int> <int> <int>
#> 1:     1     5     6
#> 2:     2     6     8
#> 3:     3     7    10
#> 4:     4     8    12

reprex package(v2.0.1)于2022年2月25日创建

数据.在开发版本中,table包还有一个新的"语言编程"接口,但我能说的最好的情况是,它只允许符号,不允许表达式.

https://rdatatable.gitlab.io/data.table/news/index.html

R相关问答推荐

使用log 10转换绘制geom_smooth

当y大于阈值和值范围时,在时间序列中突出显示区域

R包terra在投影时如何决定模板格栅属性?

我可以截断10字节的扩展数并转换为8字节的double吗?

如何在弹性表中为类别值的背景上色

如何删除R中除某些特定名称外的所有字符串?

如何根据组大小应用条件过滤?

如何编辑ggplot的图例字使用自定义对象(gtable)?'

为什么观察不会被无功值变化触发?

R Sapply函数产生的值似乎与for循环方法略有不同

将数据集中的值增加到当前包含的最大值

是否可以创建一个ggplot与整洁判断的交互作用

如何在ggplot2中绘制具有特定 colored颜色 的连续色轮

仅在R中的数据集开始和结束时删除所有 Select 列的具有NA的行

基于Key->Value数据帧的基因子集相关性提取

来自程序包AFEX和amp;的类/函数和NICE_TABLE&冲突

我们如何在R中透视数据并在之后添加计算

R中时间间隔的大向量与参考时间间隔的相交

网络抓取新闻标题和时间

如何在刻面和翻转堆叠条形图中对齐geom_text()