dplyr 0.7.5 изменение поведения select () - PullRequest
0 голосов
/ 07 июня 2018

select () в dplyr 0.7.5 возвращает результат, отличный от 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

Это ошибка или функция?

1 Ответ

0 голосов
/ 12 июня 2018

IMO это могло быть , считалось ошибкой в ​​0.7.4 , и теперь исправлено / более удобно для пользователя.

С переходом на tidyselect логика сталанемного сложнее.Если вы сравните dplyr::select_vars с новым tidyselect::vars_select (это варианты, используемые dplyr:::select.data.frame в 0.7.4 и 0.7.5 соответственно), вы обнаружите, что строка ниже теряет имена для с именем& quote (strings) case в 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, но получает overscope вариант c(), который обрабатывает строки (через аргумент overscope).Смотри tidyselect:::vars_c.Таким образом, после этой строки регистр c(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

is_character, и больше не сохраняется в последующем коде, в отличие от вышеупомянутого с rlang::eval_tidy.

Если вы посмотрите на эти функции в rlang, тот факт, что overscope_eval_next мягко устарел в пользу eval_tidy, может сбить вас с толку, учитывая вышесказанное.Но здесь я предполагаю, что tidyselect просто еще не «очищен» по этому поводу (необходимо также устранить несоответствия имен и т. Д., Так что это перезапись не только одной строки с вызовом).Но в итоге eval_tidy можно использовать таким же образом сейчас и, вероятно, будет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...