提取运算符`$`()返回函数内的零长度向量

时间:2018-04-26 16:19:11

标签: r function scoping

当我在函数中使用提取运算符`$()时遇到问题。如果我在循环之外遵循相同的逻辑,那么问题就不存在了,所以我假设可能存在一个我不知道的范围问题。

一般设置:

## Function should take a string for the following:
##  cat_var - string with the categorical variable name as it appears in df
##  level - a level of cat_var appearing in df
##  df - data frame to operate on.  Function assumes it has a column 
##    "continuous".
extract_sample <- function(cat_var, level, df = my_df) {

  index <- which(`$`(df, cat_var) == level)

  df$continuous[index]

}

## Does not work.
extract_sample(cat_var = "cat_1", level = "a")

这个过程我试图动态重现:

numeric(0)

但是一旦我将这个逻辑编程成一个函数,它就失败了:

{{1}}

这将返回{{1}}。对我缺少什么的想法?也欢迎其他方法。

3 个答案:

答案 0 :(得分:4)

问题不在于功能,而是$处理输入的方式。

cat_var = "cat_1"
length(`$`(my_df,"cat_1"))
#> [1] 100
length(`$`(my_df,cat_var))
#> [1] 0 

您可以使用[[来达到预期的效果。

cat_var = "cat_1"
length(`[[`(my_df,"cat_1"))
#> [1] 100
length(`[[`(my_df,cat_var))
#> [1] 100

<强>更新

已经注意到使用[[这种方式很丑陋。它是。当你想写lapply(stuff,'[[',1)

之类的东西时,这很有用

在这里,你应该把它写成my_df[[cat_var]]

另外,this question/answer更详细地介绍了为什么$无法以您希望的方式运作的原因。

答案 1 :(得分:3)

问题是$是非标准的,因为当你不引用参数输入时,它仍会尝试解析它并使用你输入的内容,即使这是为了参考另一个变量。

或者更简单,因为@ 42将其放在linked question中的第一条评论中:

  

“$”函数不评估其参数,而“[[”表示。

这是一个更简单的数据集作为例子。

my_df <- data.frame(a=c(1,2))
v <- "a"

比较通常的用法;前两个给出相同的结果,如果你不引用它,它会解析它。所以第三个(现在)显然不能正常工作。

my_df$"a"
## [1] 1 2

my_df$a
## [1] 1 2

my_df$v
## NULL

这正是发生在你身上的事情:

`$`(my_df, "a")
## [1] 1 2

`$`(my_df, v)
## NULL

相反,我们需要先评估v,然后再使用$发送给do.call

do.call(`$`, list(my_df, v))
## [1] 1 2

或者,更合适的是,使用首先评估参数的[[版本。

`[[`(my_df, v)
## [1] 1 2

答案 2 :(得分:1)

问题在于您索引列的方式。这只是对你的一点点调整:

extract_sample <- function(cat_var, level, df = my_df) {
  index <- df[, cat_var] == level
  df$continuous[index]
}

动态使用它:

> extract_sample(cat_var = "cat_2", level = "d")
 [1] -0.42769207 -0.75650031  0.64077840 -1.02986889  1.34800344  0.70258431  1.25193247
 [8] -0.62892048  0.48822673  0.10432070  1.11986063 -0.88222370  0.39158408  1.39553002
[15] -0.51464283 -1.05265106  0.58391650  0.10555913  0.16277385 -0.55387829 -1.07822831
[22] -1.23894422 -2.32291394  0.11118881  0.34410388  0.07097271  1.00036812 -2.01981056
[29]  0.63417799 -0.53008375  1.16633422 -0.57130500  0.61614135  1.06768285  0.74182293
[36]  0.56538633  0.16784205 -0.14757303 -0.70928924 -1.91557732  0.61471302 -2.80741967
[43]  0.40552376 -1.88020372 -0.38821089 -0.42043745  1.87370600 -0.46198139  0.10788358
[50] -1.83945868 -0.11052531 -0.38743950  0.68110902 -1.48026285