【问题标题】:Indexing a dataframe with $ inside a function?在函数内用 $ 索引数据框?
【发布时间】:2013-07-16 18:00:38
【问题描述】:

许多 R 教科书鼓励使用 $ 从 data.frames^ 中检索变量(列)。但是,我发现这在函数内部不起作用,我不知道为什么。

data(BOD)
print(BOD)

# These work. 
BOD$'demand'
BOD[ ,'demand']

# This works.
myFunc1 <- function(x, y){
  z <- x[ , y]
  return(z)
}
out <- myFunc(BOD, 'demand')

# This doesn't work.
myFunc2 <- function(x, y){
  z <- x$y
  return(z)
}
out <- myFunc2(BOD, 'demand')

我注意到在 R 语言定义中它说:

使用 $ 的形式适用于递归对象,例如列表和对列表。它只允许将文字 > 字符串或符号作为索引。也就是说,索引是不可计算的:对于需要计算表达式以找到索引的情况,请使用 x[[expr]]。当 $ 应用于 >非递归对象时,结果通常为 NULL:从 R 2.6.0 开始,这是一个错误。

上面的 myFunc2 是否是一个没有为 $ 提供文字字符串的示例?

^ Zuur 2009 年“R 初学者指南”第 61 页

^ Spector 2008“使用 R 进行数据操作”第 26、64、69 页

【问题讨论】:

  • 你在函数内部做的事情在函数外部也不起作用:y = 'demand'; z = BOD$y
  • fortune(312) 在这里再次相关:“这里的问题是 $ 符号是一个神奇的快捷方式,如果使用不正确,就像任何其他魔法一样,可能会产生相当于把自己变成蟾蜍的程序化效果"

标签: r function indexing


【解决方案1】:

我个人认为美元运算符 $ 在 R 控制台中很方便且有用。它允许完成和部分命名功能。 $ 对于交互模式很有用。但是如果你想在你的函数中使用它,你应该像这样使用do.call 创建一个调用:

myFunc2 <- function(x, y){
  z <- do.call('$',list(x,y))
  return(z)
}
myFunc2(BOD,'demand')
[1]  8.3 10.3 19.0 16.0 15.6 19.8

但正如您所提到的,这里使用[ 更简单:

myFunc2 <- function(x, y){
  z <-     x[,y]
  return(z)
}

【讨论】:

    【解决方案2】:

    你也可以使用 [[ 代替 $

    myFunc2 <- function(x, y){
    +     z <- x[[y]]
    +     return(z)
    + }
    > myFunc2(BOD, 'demand')
    [1]  8.3 10.3 19.0 16.0 15.6 19.8
    

    【讨论】:

      【解决方案3】:

      如果您想完美模仿$ 运算符,您可以使用[[ 并将参数exact 设置为FALSE 以允许部分匹配。

      BOD <- data.frame(demand = 1:10)
      
      myFunc2 <- function(x, y) x[[y, exact = FALSE]]
      
      BOD$dem
      ## [1]  1  2  3  4  5  6  7  8  9 10
      
      BOD[["dem"]]
      ## NULL
      
      myFunc2(BOD, "dem")
      ## [1]  1  2  3  4  5  6  7  8  9 10
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-27
        • 1970-01-01
        • 2017-12-10
        • 2016-07-03
        • 2020-06-17
        • 2020-10-22
        • 1970-01-01
        • 2019-06-10
        相关资源
        最近更新 更多