在data.table中的函数内部子集行

时间:2019-08-19 06:12:08

标签: r data.table

我试图在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")

所以问题出在选择函数内的列。

我尝试了evalsubstitutequotedeparse的组合,引用和取消引用了要传递的列名,但都无济于事。我也尝试了subset,但遇到了同样的问题。 小插图在j中描述了如何执行此操作,但在i中却没有描述。不知道我是否错过了明显的事情或者我只是在想错,但是我应该怎么做呢?

4 个答案:

答案 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)

  

我尝试了evalsubstitutequotedeparse的组合,引用和取消引用了要传递的列名,但都无济于事。

你可以

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.nameas.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