当使用命名向量指定列时,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_vars
新tidyselect::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/