data.table 中的非标准评估
Non standard evaluation of by in data.table
我对 data.table
中 by
的评价感到困惑。 将 LJ
和 LJ2
的功能合并为一个功能的正确方法是什么?
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)
我认为这是个坏主意。让用户始终传递一个字符值。你可以这样做:
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
一些由其他人准备的输入文件,就会发生这种情况。
可以处理这种极端情况的替代方案是:
LJ4 <- function(dt_x_, dt_y_, by_)
{
by_ <- substitute(by_)
if (!is.character(by_)) by_ <- deparse(by_)
dt_y_[dt_x_, on = by_]
}
我对 data.table
中 by
的评价感到困惑。 将 LJ
和 LJ2
的功能合并为一个功能的正确方法是什么?
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)
我认为这是个坏主意。让用户始终传递一个字符值。你可以这样做:
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
一些由其他人准备的输入文件,就会发生这种情况。
可以处理这种极端情况的替代方案是:
LJ4 <- function(dt_x_, dt_y_, by_)
{
by_ <- substitute(by_)
if (!is.character(by_)) by_ <- deparse(by_)
dt_y_[dt_x_, on = by_]
}