【问题标题】:Non standard evaluation of by in data.tabledata.table中by的非标准评估
【发布时间】:2016-09-08 09:49:24
【问题描述】:

我对@9​​87654322@ 中的by 的评估感到迷茫。 LJLJ2 的功能合并为一个功能的正确方法是什么?

LJ <- function(dt_x_, dt_y_, by_)
{
    merge(
        dt_x_,
        dt_y_,
        by = eval(substitute(by_)), all.x = TRUE, sort = FALSE)
}
LJ2 <- function(dt_x_, dt_y_, by_)
{
    merge(
        dt_x_,
        dt_y_,
        by = deparse(substitute(by_)), all.x = TRUE, sort = FALSE)
}
LJ(
    data.table(A = c(1,2,3)),
    data.table(A = c(1,2,3), B = c(11,12,13)), 
    "A")
LJ2(
    data.table(A = c(1,2,3)),
    data.table(A = c(1,2,3), B = c(11,12,13)), 
    A)

【问题讨论】:

  • 我得到两个函数的输出相同。目前尚不清楚您的意图
  • 这与 data.table 无关,merge.data.frame 的行为相同

标签: r nse


【解决方案1】:

我认为这是个坏主意。让用户始终传递一个字符值。你可以这样做:

LJ3 <- function(dt_x_, dt_y_, by_)
{ 
  by_ <- gsub('\"', "", deparse(substitute(by_)), fixed = TRUE)
  dt_y_[dt_x_, on = by_] 
}

LJ3(
  data.table(A = c(4,1,2,3)),
  data.table(A = c(1,2,3), B = c(11,12,13)), 
  A)
#   A  B
#1: 4 NA
#2: 1 11
#3: 2 12
#4: 3 13

LJ3(
  data.table(A = c(4,1,2,3)),
  data.table(A = c(1,2,3), B = c(11,12,13)), 
  "A")
#   A  B
#1: 4 NA
#2: 1 11
#3: 2 12
#4: 3 13

此问题与 data.table 无关。 merge.data.table 中的 by 参数始终需要一个字符值,on 也是如此。

编辑: @eddi 指出,如果您的列名中包含实际的 ",上述操作将失败(一般情况下您应该避免这种情况,但如果您使用 fread some其他人准备的输入文件)。

可以处理这种边缘情况的替代方法是:

LJ4 <- function(dt_x_, dt_y_, by_)
{ 
  by_ <- substitute(by_)
  if (!is.character(by_)) by_ <- deparse(by_)
  dt_y_[dt_x_, on = by_] 
}

【讨论】:

  • 仅供参考,on 在开发版本中接受 .() 样式的参数,我猜部分是为了使非 equi 连接更容易。 1.9.7 新闻第 32 和 33 条:github.com/Rdatatable/data.table/blob/master/NEWS.md
  • 感谢您的提醒。回答时我总是参考 CRAN 版本。我自己需要一个稍微稳定的版本,所以我什至不安装 devel 版本,除非我需要测试一些东西以确保未来的兼容性。
  • 如果列名中实际包含引号,则此 gsub 方法将失败。我只是检查substitute(by_) 是否是字符,如果不是,则仅解析。
  • @eddi 感谢您的建议。
猜你喜欢
  • 1970-01-01
  • 2019-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-10
  • 2016-09-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多