我正在尝试将data.table
的参数用于子集(并对该子集应用均值)。基本上我将传递给函数的两个键和第三个键的几个元素;这似乎让人感到困惑R
,但是当在函数环境之外完成时,操作完全符合预期。
这是一个基本上得到我想要做的事情的例子;它返回一个不正确的解决方案,而我自己的代码产生错误(下面粘贴的文本):
set.seed(12345)
dt<-data.table(yr=rep(2000:2005,each=20),
id=paste0(rep(rep(1:10,each=2),6)),
deg=paste0(rep(1:2,60)),
var=rnorm(120),
key=c("yr","id","deg"))
fcn <- function(yr,ids,deg){
dt[.(yr,ids,deg),mean(var)]
}
fcn(2004,paste0(1:3),"1")
这是一个答案,但这是完全错误的(在一秒钟内更多)。如果我手工完成,那就没问题了:
> fcn(2004,paste0(1:3),"1")
[1] 0.1262586
> dt[yr==2004&id %in% paste0(1:3)°=="1",mean(var)]
[1] 0.4374115
> dt[.(2004,paste0(1:3),"1"),mean(var)]
[1] 0.4374115
为了破解正在发生的事情,我将fcn
代码更改为:
fcn <- function(yr,ids,deg){
dt[.(yr,ids,deg),]
}
哪个收益率:
> fcn(2004,paste0(1:3),"1")
yr id deg var
1: 2000 1 1 0.5855288
2: 2000 2 2 -0.4534972
3: 2000 3 1 0.6058875
4: 2000 1 2 0.7094660
5: 2000 2 1 -0.1093033
---
116: 2005 2 2 -1.3247553
117: 2005 3 1 0.1410843
118: 2005 1 2 -1.1562233
119: 2005 2 1 0.4224185
120: 2005 3 2 -0.5360480
基本上,fcn
已完成否子集化!为什么会这样?真的很沮丧。
如果我只传递一个密钥而不是三个,dt
子集只在中间密钥上。奇怪:
> fcn(2004,"1","1")
yr id deg var
1: 2000 1 1 0.5855288
2: 2000 1 2 0.7094660
3: 2000 1 1 0.5855288
4: 2000 1 2 0.7094660
5: 2000 1 1 0.5855288
---
116: 2005 1 2 -1.1562233
117: 2005 1 1 0.2239254
118: 2005 1 2 -1.1562233
119: 2005 1 1 0.2239254
120: 2005 1 2 -1.1562233
但是,如果我只将中间键传递给函数,它可以正常工作:
fcn <- function(ids){
dt[.(2004,ids,"1")]
}
> fcn(paste0(1:3))
yr id deg var
1: 2004 1 1 0.6453831
2: 2004 2 1 -0.3043691
3: 2004 3 1 0.9712207
最终编辑:问题解决了,但知道到底出了什么问题仍然很好:
重命名参数:
fcn <- function(yyr,ids,ddeg){
dt[.(yyr,ids,ddeg),mean(var)]
}
关于重新使用列名作为变量名称的问题似乎引起了一个问题 - 但我仍然没有完全理解出了什么问题。
答案 0 :(得分:7)
问题是您在i-expression
内使用了列的名称,但期望它们是data.table
的名称 。您可以在函数中重命名变量名称,也可以在外部构造连接data.table
,然后使用单个名称data.table
将始终使用外部环境的事实:
fcn <- function(yr,ids,deg){
tmp = data.table(yr, ids, deg)
dt[tmp, mean(var)]
}
fcn(2004, paste0(1:3), "1")
#[1] 0.4374115
见FAQ 2.12-2.13。