当使用命名向量指定列时,dplyr 0.7.5 中的 select() 返回与 dplyr 0.7.4 不同的结果。

library(dplyr)
df <- data.frame(a = 1:5, b = 6:10, c = 11:15)
print(df)
#>   a  b  c
#> 1 1  6 11
#> 2 2  7 12
#> 3 3  8 13
#> 4 4  9 14
#> 5 5 10 15

# a named vector
cols <- c(x = 'a', y = 'b', z = 'c')
print(cols)
#>  x   y   z
#> "a" "b" "c"

# with dplyr 0.7.4
# returns column names with vector values
select(df, cols)
#>   a  b  c
#> 1 1  6 11
#> 2 2  7 12
#> 3 3  8 13
#> 4 4  9 14
#> 5 5 10 15

# with dplyr 0.7.5
# returns column names with vector names
select(df, cols)
#>   x  y  z
#> 1 1  6 11
#> 2 2  7 12
#> 3 3  8 13
#> 4 4  9 14
#> 5 5 10 15

这是错误还是功能?

最佳答案

IMO 可能将 视为 0.7.4 中的错误,现在已修复/更加用户友好。

随着移动到 tidyselect ,逻辑变得更加复杂。
如果你比较dplyr::select_varstidyselect::vars_select(这些是分别在0.7.4和0.7.5使用的变异由dplyr:::select.data.frame),你可以找到该线之下在失去名字命名为引用的 (串)案0.7.4:

ind_list <- map_if(ind_list, is_character, match_var, table = vars)

# example:
dplyr:::select.data.frame(mtcars, c(a = "mpg", b = "disp"))

请注意,这是 不是一般命名向量的问题 ,因为典型的不加引号的情况总是好的:
dplyr:::select.data.frame(mtcars, c(a = mpg, b = disp))
# (here the names are indeed "a" and "b" afterwards)

有一行代码处理 c() 的用法:
ind_list <- map_if(ind_list, !is_helper, eval_tidy, data = names_list)
eval_tidy 来自 rlang 包,并且在上面的行中将针对有问题的调用返回以下内容:
[[1]]
 a      b
 "mpg" "disp"

现在有了 tidyselect ,我们有了一些额外的处理,参见 https://github.com/tidyverse/tidyselect/blob/master/R/vars-select.R

特别是, vars_select_eval 有以下行,它处理 c() 的用法:
ind_list <- map_if(quos, !is_helper, overscope_eval_next, overscope = overscope)
overscope_eval_next 再次来自 rlang 包并调用与 eval_tidy 相同的例程,但它接收到 c() 的超范围变体(处理 132315 的参数 1323141)。见 overscope
所以在这行之后, tidyselect:::vars_c 的情况变得与 c(a = "mpg", b = "disp") 相同:
[[1]]
a b   # these are the names
1 3   # these are the positions of the selected cols
c(a = mpg, b = disp) 然后在后续代码中不再成立,与上面的 is_character 相反。

如果您在 rlang::eval_tidy 中查看这些函数,那么 rlang 已被软弃用而支持 overscope_eval_next 的事实可能会让您感到困惑。但在这里我猜 eval_tidy 还没有被“清理”出来(命名不一致等也必须解决,所以它不仅仅是对调用的一行的重写)。但最终 tidyselect 现在可以以同样的方式使用,而且可能会如此。

关于r - dplyr 0.7.5 更改 select() 行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50748239/

10-12 20:53