【问题标题】:Object not found for lapply data.table within function函数内未找到 lapply data.table 的对象
【发布时间】:2016-12-21 20:34:57
【问题描述】:

假设我有以下 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”

r 进一步向上的分配工作正常。同样,如果在函数内部,我通过

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    我猜你想从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))
    

    【讨论】:

      【解决方案2】:

      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 专家可以在这里澄清。

      【讨论】:

      • 使用匿名函数有效。我想我是用“[”结合 lapply 和 data.table 来推动它。
      • @user5577796 在使用可选参数时,它可能与lapply 的环境有关。如果您的原始函数 f 使用驻留在全局环境中的 columnName 而不是 columnName1,则它可以工作
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-16
      相关资源
      最近更新 更多