我试图在R函数中以编程方式对data.table的行进行子集化。预期效果如下:
dt <- data.table(id = 1:5, variable = c("test","data","data", "is", "fun"))
dt[variable == "data"]
id variable
1: 2 data
2: 3 data
如果我定义函数:
dtSubset <- function(df, col, str) {
df[col == str]
}
dtSubset(df, "variable", "data")
我得到一个0行表。
以下作品:
dtSubset <- function(df, str) {
dt[variable == str]
}
dtSubset(df, "data")
所以问题出在选择函数内的列。
我尝试了eval
,substitute
,quote
和deparse
的组合,引用和取消引用了要传递的列名,但都无济于事。我也尝试了subset
,但遇到了同样的问题。
小插图在j
中描述了如何执行此操作,但在i
中却没有描述。不知道我是否错过了明显的事情或者我只是在想错,但是我应该怎么做呢?
答案 0 :(得分:2)
您还可以使用get
来使函数正常工作:
dtSubset <- function(df, col, str) {
df[get(col) == str]
}
现在dtSubset(dt, "variable", "data")
将为您带来预期的结果:
id variable 1: 2 data 2: 3 data
答案 1 :(得分:2)
我尝试了
eval
,substitute
,quote
和deparse
的组合,引用和取消引用了要传递的列名,但都无济于事。
你可以
subit <- function(d, cc, vv){
ex = substitute( d[cc == vv], list(cc = as.name(cc), vv = vv) )
print(ex)
eval(ex)
}
subit(dt, "variable", "data")
d[variable == "data"]
id variable
1: 2 data
2: 3 data
as.name
或as.symbol
删除"variable"
的引号。
通过这种方法,您可以利用data.tables优化的“自动索引”。 @sindri_baldur的答案还通过创建一个索引并加入索引来使用索引。第三种选择是即时加入:
jit <- function(d, cc, vv) d[.(unique(vv)), on=cc, nomatch=0]
jit(dt, "variable", "data")
此“子集联接”的一些替代方法在这里:Perform a semi-join with data.table
答案 2 :(得分:1)
如果要在函数中传递带引号的变量,可以使用[[
dtSubset <- function(df, col, str) {
df[df[[col]] == str, ]
}
dtSubset(dt, "variable", "data")
# id variable
#1: 2 data
#2: 3 data
答案 3 :(得分:1)
另一个选择是在函数内部使用setkey()
:
dtSubset <- function(df, col, str) {
setkeyv(df, col)[str]
}
dtSubset(dt, "variable", "data")
# id variable
# 1: 2 data
# 2: 3 data