R:'无效的下标类型符号'

时间:2018-04-02 11:25:49

标签: r dplyr non-standard-evaluation

我目前正在研究2nd edition of Hadley's Advanced R book中有关表达式和quasiquotation的主题。在练习部分20.6.5中,任务是

  

“实施arrange_desc(),dplyr::arrange()的变体,默认按降序排序。”

在玩耍的时候,我发现了一些令我困惑的事情。首先,我只是尝试编写一个函数,该函数将采用数据框和变量作为输入。我想自动引用变量来镜像dplyr::arrange()的行为

arrange_desc2 <- function(.data, ...) {
   my_args <- enexprs(...)
   new_order <- order(.data[[my_args[[1]]]])
   return(list(my_args = my_args, new_order = new_order))
}

df <- data.frame(a = c(4, 3, 2, 1), 
                 b = c('d', 'c', 'b', 'a'))

arrange_desc2(df, a)

# $my_args
# $my_args[[1]]
# a

# $new_order
# [1] 4 3 2 1

这很有效,但坦率地说,我不明白为什么:毕竟,我在这里使用符号进行子集化。深入挖掘,我注意到如果我写这样的代码,我会收到一个错误:

arrange_desc3 <- function(.data, ...) {
   my_args <- enexprs(...)
   new_order <- order(.data[, my_args[[1]]])
   return(list(my_args = my_args, new_order = new_order))
}

arrange_desc3(df, a)
# Error in .subset(x, j) : invalid subscript type 'symbol'

为什么我可以使用符号对列表进行子集(它是否与此处的表达式相同?)为什么符号显然是使用列表作为环境进行评估但仅在使用[[时,而不是在使用时{ {1}}?换句话说,有什么区别:

[

1 个答案:

答案 0 :(得分:0)

如果我们要转换为symbol,那么eval uate it

a[eval(as.symbol("a"))]
#[1] 1 1 3 4

sym

中的rlang相同
a[eval(rlang::sym("a"))]
#[1] 1 1 3 4

关于更改的代码无效的原因,order适用于vector或列,使用drop = FALSE,它是data.frame