【问题标题】:Subsetting rows inside function in data.table在 data.table 中的函数内子集行
【发布时间】:2019-08-19 06:12:08
【问题描述】:

我正在尝试在 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 中没有。不知道我是否遗漏了一些明显的东西,或者我只是想错了,但是我应该怎么做呢?

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    您也可以使用get 来使您的功能正常工作:

    dtSubset <- function(df, col, str) {
      df[get(col) == str]
    }
    

    现在dtSubset(dt, "variable", "data") 将为您提供预期的结果:

       id variable
    1:  2     data
    2:  3     data
    

    【讨论】:

    • get 是我错过的部分。最终做了一个deparse(substitute(col))get,因此可以不加引号地提供该列。非常感谢。
    【解决方案2】:

    如果您想在函数中传递带引号的变量,您可以使用 [[ 对列进行子集化

    dtSubset <- function(df, col, str) {
         df[df[[col]] == str, ]
    }
    
    dtSubset(dt, "variable", "data")
    
    #   id variable
    #1:  2     data
    #2:  3     data
    

    【讨论】:

      【解决方案3】:

      我尝试了 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

      【讨论】:

        【解决方案4】:

        另一种选择是在函数内部使用setkey()

        dtSubset <- function(df, col, str) {
          setkeyv(df, col)[str]
        }
        
        dtSubset(dt, "variable", "data")
        #    id variable
        # 1:  2     data
        # 2:  3     data
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-08-18
          • 1970-01-01
          • 2019-10-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-26
          相关资源
          最近更新 更多