当使用命名向量指定列时,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
Run Code Online (Sandbox Code Playgroud)
这是一个错误还是一个功能?
IMO 它可能被认为是 0.7.4 中的错误,现在已修复/更加用户友好。
随着转移到tidyselect,逻辑变得更加复杂了。如果dplyr::select_vars与新版本tidyselect::vars_select(这些分别是 0.7.4 和 0.7.5 中使用的变体)进行比较,您会发现下面的行丢失了 0.7.4 中命名和引用dplyr:::select.data.frame(字符串)情况的名称:
ind_list <- map_if(ind_list, is_character, match_var, table = vars)
# example:
dplyr:::select.data.frame(mtcars, c(a = "mpg", b = "disp"))
Run Code Online (Sandbox Code Playgroud)
请注意,这通常不是命名向量的问题,因为典型的不带引号的情况总是好的:
dplyr:::select.data.frame(mtcars, c(a = mpg, b = disp))
# (here the names are indeed "a" and "b" afterwards)
Run Code Online (Sandbox Code Playgroud)
有一行代码处理以下用法c():
ind_list <- map_if(ind_list, !is_helper, eval_tidy, data = names_list)
Run Code Online (Sandbox Code Playgroud)
eval_tidy来自rlang包,并且在上面的行中将为有问题的调用返回以下内容:
[[1]]
a b
"mpg" "disp"
Run Code Online (Sandbox Code Playgroud)
现在有了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)
Run Code Online (Sandbox Code Playgroud)
overscope_eval_next再次来自rlang包并调用相同的例程eval_tidy,但它接收处理字符串的超出范围的变体(通过参数)。看。因此,在这一行之后,情况变得与以下内容相同:c()overscopetidyselect:::vars_cc(a = "mpg", b = "disp")c(a = mpg, b = disp)
[[1]]
a b # these are the names
1 3 # these are the positions of the selected cols
Run Code Online (Sandbox Code Playgroud)
is_characterthen 在后续代码中不再成立,与上面的rlang::eval_tidy.
如果您查看 中的这些函数,考虑到上述情况,软弃用并支持 的rlang事实可能会让您感到困惑。但在这里我猜想这还没有被“清理”(命名不一致等问题也必须得到解决,所以它不仅仅是对调用的一行进行重写)。但最终现在可以以同样的方式使用,并且可能会如此。overscope_eval_nexteval_tidytidyselecteval_tidy
| 归档时间: |
|
| 查看次数: |
214 次 |
| 最近记录: |