如何在具有相同名称的列的 data.table 中引用函数参数?
How do I reference a function parameter inside inside a data.table with a column of the same name?
这里,我有一个data.tablefoo
foo <- data.table(t = c(1,1,2,2,3), b = rnorm(5))
foo
t b
1: 1 0.07014277
2: 1 1.71144087
3: 2 -0.60290798
4: 2 -0.47216639
5: 3 -0.63537131
和一个函数,myfunc()
myfunc <- function(dt, t){
# Subset dt by t, then do stuff
dt <- dt[J(t = t), by = "t"]
# Complicated stuff here..
score <- mean(dt$b)
return(score)
}
myfunc()
有两个参数:
dt
data.table 操作
t
可用于子集 dt
的 t 值(当然在 t 列 上)
我的问题是,在我的子集操作 dt <- dt[J(t = t), by = "t"]
中,我不知道如何让 R 为第二个 t 引用函数变量 t。我尝试了 dt <- dt[J(t = get(t, -1)), by = "t"]
的变体,但没有成功。
我知道我可能应该只更改我的函数变量名称,但实际上它们非常冗长和具体,我宁愿不这样做。另请注意,实际上,myfunc()
是一个复杂的绘图函数。
歧义不在 base-function-t
与名为“t”的列之间。它在名为 t
的参数级别和名为 t
的列> 这是一个成功的修改函数(至少如果之前有一个 setkey(foo, "t") 操作:
myfunc <- function(dt, d){
# Subset dt by t, then do stuff
dt1 <- dt[ t==d]
# Complicated stuff here..
score <- dt1[ , paste(b, collapse="_")]
return(score)
}
myfunc(foo, d=1)
#[1] "a_b"
显然我需要想出一个对字符变量列有意义的内部函数。这似乎可以解决您在使用名为“t”的列时遇到的明显问题。只需将函数参数列表中的参数名称更改为“t”以外的名称。 data.table
j-calls 中的作用域和环境(作为第二个参数计算的表达式)与常规 R 中的不同。
- 一个可能的选择是:
myfunc <- function(dt, t){
env <- environment()
dt <- dt[t==get('t',env)]
mean(dt$b)
}
- 另一种方法:虽然严格来说可能不是您当前问题的“解决方案”,但您可能会发现它很有趣。考虑
data.table
版本 >= 1.14.3。在这种情况下,我们可以使用DT[i,j,by,env,...]
的env
参数来表示数据表列为"t"
,函数参数为t
。请注意,即使 dt
包含名为 col
和 val
的列,这也适用于具有函数参数 t
的列 t
myfunc <- function(dt, t){
dt <- dt[col==val, env=list(col="t", val=t)]
mean(dt$b)
}
在这两种情况下,用法和输出如下:
用法
myfunc(dt = foo, t = 3)
输出:
[1] 0.1292877
输入:
set.seed(123)
foo <- data.table(t = c(1,1,2,2,3), b = rnorm(5))
foo
看起来像这样:
> foo
t b
1: 1 -0.56047565
2: 1 -0.23017749
3: 2 1.55870831
4: 2 0.07050839
5: 3 0.12928774
这里,我有一个data.tablefoo
foo <- data.table(t = c(1,1,2,2,3), b = rnorm(5))
foo
t b
1: 1 0.07014277
2: 1 1.71144087
3: 2 -0.60290798
4: 2 -0.47216639
5: 3 -0.63537131
和一个函数,myfunc()
myfunc <- function(dt, t){
# Subset dt by t, then do stuff
dt <- dt[J(t = t), by = "t"]
# Complicated stuff here..
score <- mean(dt$b)
return(score)
}
myfunc()
有两个参数:
dt
data.table 操作t
可用于子集dt
的 t 值(当然在 t 列 上)
我的问题是,在我的子集操作 dt <- dt[J(t = t), by = "t"]
中,我不知道如何让 R 为第二个 t 引用函数变量 t。我尝试了 dt <- dt[J(t = get(t, -1)), by = "t"]
的变体,但没有成功。
我知道我可能应该只更改我的函数变量名称,但实际上它们非常冗长和具体,我宁愿不这样做。另请注意,实际上,myfunc()
是一个复杂的绘图函数。
歧义不在 base-function-t
与名为“t”的列之间。它在名为 t
的参数级别和名为 t
的列> 这是一个成功的修改函数(至少如果之前有一个 setkey(foo, "t") 操作:
myfunc <- function(dt, d){
# Subset dt by t, then do stuff
dt1 <- dt[ t==d]
# Complicated stuff here..
score <- dt1[ , paste(b, collapse="_")]
return(score)
}
myfunc(foo, d=1)
#[1] "a_b"
显然我需要想出一个对字符变量列有意义的内部函数。这似乎可以解决您在使用名为“t”的列时遇到的明显问题。只需将函数参数列表中的参数名称更改为“t”以外的名称。 data.table
j-calls 中的作用域和环境(作为第二个参数计算的表达式)与常规 R 中的不同。
- 一个可能的选择是:
myfunc <- function(dt, t){
env <- environment()
dt <- dt[t==get('t',env)]
mean(dt$b)
}
- 另一种方法:虽然严格来说可能不是您当前问题的“解决方案”,但您可能会发现它很有趣。考虑
data.table
版本 >= 1.14.3。在这种情况下,我们可以使用DT[i,j,by,env,...]
的env
参数来表示数据表列为"t"
,函数参数为t
。请注意,即使dt
包含名为col
和val
的列,这也适用于具有函数参数
t
的列 t
myfunc <- function(dt, t){
dt <- dt[col==val, env=list(col="t", val=t)]
mean(dt$b)
}
在这两种情况下,用法和输出如下:
用法
myfunc(dt = foo, t = 3)
输出:
[1] 0.1292877
输入:
set.seed(123)
foo <- data.table(t = c(1,1,2,2,3), b = rnorm(5))
foo
看起来像这样:
> foo
t b
1: 1 -0.56047565
2: 1 -0.23017749
3: 2 1.55870831
4: 2 0.07050839
5: 3 0.12928774