我目前正在研究 Hadley 的 Advanced R book 第 2 版中关于表达式和准引用的主题。在练习部分 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'
为什么我可以使用符号对列表进行子集化(它与此处的表达式相同吗?)以及为什么符号显然是使用列表作为环境评估的,但仅在使用时而[[
不是在使用时[
?换句话说,有什么区别:
a <- c(1, 1, 4, 3)
a[a]
# [1] 1 1 3 4
a[sym("a")] # but list(a = a)[[sym("a")]] will work!
# Error in a[sym("a")] : invalid subscript type 'symbol'