R data.table使用外部定义的函数进行lapply

时间:2014-06-10 22:58:53

标签: r data.table

此问题与R - pass fixed columns to lapply function in data.tableweighted means by group and column有关,但有些不同。

我希望有一个固定列与data.table中的所有其他列进行交互。一个简单的例子来说明:

DT <- data.table(y = rnorm(10), x1 = rnorm(10), x2 = rnorm(10))
DT[, lapply(c('x1', 'x2'), function(x) get(x) * y)]

现在假设操作比乘法复杂得多,因此我想在data.table范围之外定义一个独立函数:

fun <- function(x) {
    return(get(x) * y)
}
DT[, lapply(c('x1', 'x2'), fun)]
Error in get(x) : object 'x1' not found

显然变量范围存在问题,因为在data.table之外定义的函数无法看到变量。是否有任何聪明的技巧来定义data.table之外的功能并仍然可以使用lapply

1 个答案:

答案 0 :(得分:2)

如果您尝试将字符串和命名变量的引用组合在一起,您将自己包装成结。 (以及通过引用&#34;全局&#34;函数内的变量)

最简单的方法是定义get寻找x的位置,(和y

这是重写的功能,以便您可以告诉它在哪里看。

fun <- function(x,y,wherex=parent.frame(),wherey=parent.frame()) {
    return(get(x,wherex) * get(y,wherey))
}

data.table检查j中的名称,并仅在必填列中加载。

在您的示例中,您不使用列名称,因此没有可用的内容。

如果您在.SD的表达式中包含j,则会在所有列中加载。您可以使用.SD作为新定义的wherex

wherey / fun个参数
DT[, lapply(c('x1', 'x2'), fun, y = 'y' , wherex=.SD, wherey=.SD)]
 #              V1         V2
 #  1: -0.27871200  1.1943170
 #  2: -0.68843421 -1.5719016
 #  3:  1.06968681  2.8358612
 #  4:  0.21201412  1.0127712
 #  5:  0.05392450  0.2487873
 #  6:  0.04473767 -0.1644542
 #  7:  5.37851536  2.9710708
 #  8:  0.23653388  0.9506559
 #  9:  1.96364756 -1.4662968
 # 10: -0.02458077 -0.1197023

请注意,您并非真的需要将其包含在[.data.table

results <- setDT(lapply(c('x1','x2'), fun, y='y', wherex=DT,wherey=DT))

将返回相同的结果。