假设我有以下R代码:
library(data.table)
L <- list(a=data.table(x=c(1,2,3),y=c(10,20,30)),
b=data.table(x=c(4,5,6),y=c(40,50,60)),
c=data.table(x=c(7,8,9),y=c(70,80,90)))
columnName <- "x"
r <- lapply(L,"[",i=get(columnName) %in% c(1,4))
f <- function(L1) {
columnName1 <- "x"
r1 <- lapply(L1,"[",i=get(columnName1) %in% c(1,4))
return(r1)
}
r1 <- f(L)
我的问题是:为什么底部r1的赋值在
函数内部失败get(columnName1)中的错误:找不到对象'columnName1'
进一步提升的分配工作正常。同样,如果在函数内部我通过&lt;&lt; - 将其更改为columnName1的全局赋值,但是我创建了一个我不想要的全局变量....我怎样才能干净地重写这样的data.table在其范围内找到columnName1?关于范围界定我错过了什么?我原以为如果它在“[”函数中找不到columnName1它会看起来一个环境“up”并在那里找到它?它必须在全球环境中查看,但不能在父文件中查找?
答案 0 :(得分:0)
我猜你想要从data.table
返回什么。如果您要返回列x
等于1和4的行,通常可以更轻松地使用列表中的单个值,然后使其与lapply
一起使用
library(data.table)
columnName1 <- "x"
L$a[get(columnName1) %in% c(1,4)]
遍历列表
lapply(L, function(x) x[get(columnName1) %in% c(1,4)])
如果你想要一个可以指定列名和行号的函数
f <- function(list, col, row) {lapply(list, function(x, lcol, lrow) x[get(lcol) %in% lrow], lcol=col, lrow=row)}
f(L, "x", c(1,4))
答案 1 :(得分:0)
lapply
糖语法可能会使这里的事情变得复杂,在这种情况下,表达式将被视为参数,这使得更难以了解表达式的评估环境。此get()
函数在与data.table()
一起使用时可能已被修改,因为签名与正常用例不同。这里的一个工作是创建自己的匿名函数,保证get
将在[.data.table
调用中进行评估。
f <- function(L1) {
columnName1 <- "x"
r1 <- lapply(L1, function(x) x[i=get(columnName1) %in% c(1,4)])
r1
}
r1 <- f(L)
r1
#$a
# x y
#1: 1 10
#$b
# x y
#1: 4 40
#$c
#Empty data.table (0 rows) of 2 cols: x,y
仍然不确定导致失败的原因,可能有些data.table
专家可以在这里澄清。