Нестандартная оценка с использованием tidyr :: expand - PullRequest
4 голосов
/ 23 сентября 2019

У меня проблемы с запуском нестандартных выражений оценки с пакетом tidyr.

По сути, я хочу развернуть два столбца, которые могут быть идентичными, или не достичь кадра данных со всеми возможнымикомбинации.Проблема в том, что это будет функция, поэтому я не буду заранее знать имя столбца.

Вот минимальный пример:

library(tidyr)

dummy <- data.frame(x = c("ex1", "ex2"), y = c('cat1', 'cat2')) # dataset

tidyr::expand(dummy, x, y) # using standard evaluation works
tidyr::expand_(dummy, c("x", "y"))  # using the deprecated syntax works

# The following did not work:

  tidyr::expand(dummy, one_of('x'), y) # using select sintax
  tidyr::expand(dummy, vars('x', 'y')) # mutate_at style
  tidyr::expand(dummy, .data[[cnae_agg]], .data[[cnae_agg]])  # mutate current style  
  tidyr::expand(dummy, sym('x'), sym('y')) # trying to convert to symbols
  tidyr::expand(dummy, !!!enquos('x', 'y')) 
  tidyr::expand(dummy, !!('x'), y) # unquosure just one element
  tidyr::expand(dummy, !!!c("x", "y")) # unquosure vector of strings
  tidyr::expand(dummy, !!!c(quo("x"), quo("y"))) # unquosure vector that is being quosured before

Итак, у меня есть два вопроса:

1) Какой правильный синтаксис должен применяться с функцией расширения tidyr?

2) Я, вероятно, прочитал главу Advanced R квазиквотация уже несколько раз, но мне все еще неясно, почему есть несколько различных «стилей» для использования nse с тидиверсом, и где именно их использовать.

Я могу в основном бросить практически все, чтобы выбрать / суммировать, что это будет работать, но при использовании мутации вещи реагируют по-разному.

Например:

  # mutate
  mutate(dummy, new_var = .data[['x']]) # mutate basic style
  mutate(dummy, new_var = !!'x') # this just attributes 'x' to all rows


  # mutate at
  mutate_at(dummy, .vars=vars('y'), list(~'a')) # this works
  mutate_at(dummy, .vars=vars(!!'y'), list(~'a')) # this also works
  mutate_at(dummy, .vars=vars('y'), list(~`<-`(.,!!'x'))) # if we try to use unquote to create an attribution it does not work
  mutate_at(dummy, .vars=vars('y'), list(~`<-`(.,vars(!!'x')))) # even using vars, which works for variable selection, doesnt suffice

  # select 
  select(dummy, x) # this works
  select(dummy, 'x') # this works
  select_at(dummy, vars(!!'x')) # this works
  select_at(dummy, 'x') # this works
  select_at(dummy, !!'x') # this doesnt work

Что приноситмне на мой 2) вопрос.

Существует ли руководство по обновлению со всеми текущими синтаксисами для стиля tidyverse с акцентом на различиях в использовании для каждого «глагола», например в «mutate» против «select» (т. Е. Когда он работаета другой нет)?

И как узнать, нужно ли мне использовать mutate или стиль выбора nse в других пакетах tidyverse, таких как tidyr?

Ответы [ 2 ]

2 голосов
/ 23 сентября 2019

Обновленное руководство по nse является аккуратным руководством по оценке .В частности, в главе 8 рассматривается ее связь с dplyr, а также общие закономерности.В вашем случае есть несколько возможных шаблонов, в зависимости от того, что вы хотите предоставить пользователю.

Шаблон 1: Просто передать точки для расширения , предоставляя пользователю полный контроль над базовым expand():

f <- function(...) {tidyr::expand(dummy, ...)}
f( x, y )    # End users specifies the columns via NSE

Pattern 2: Захватывает вводимые пользователем данные для каждой переменной и передает их в expand(), используя новый оператор "curly curly" :

g <- function( var1, var2 ) {tidyr::expand(dummy, {{var1}}, {{var2}})}
g( x, y )    # Once again, NSE, but the number of arguments is controlled

Шаблон 3: Разрешить пользователю предоставлять аргументы в качестве имен переменных ИЛИ строк.Используйте rlang::ensyms для преобразования строк в имена переменных:

h <- function(...) {tidyr::expand(dummy, !!!rlang::ensyms(...))}

# The interface now works with strings or NSE
h( "x", "y" )
h( x, y )

Шаблон 3b: Если вы хотите отключить поддержку NSE и обеспечить, чтобы пользователи предоставляли аргументы только в виде строк, тогданезначительная модификация вышеприведенного шаблона будет принимать только строки:

h2 <- function(...) {tidyr::expand(dummy, !!!rlang::syms(list(...)))}
h2( "x", "y" )    # Strings OK
h2( x, y )        # Error: object 'x' not found

Обратите внимание, что функциям NSE требуется квазиквотация для обработки символов, хранящихся во внешних переменных:

# Handling strings in external variables
str_name <- "x"
h( !!str_name, "y" )
h2( str_name, "y" )    # h2 doesn't support NSE; no !! needed

# Handling variable names as unevaluated expressions (NOT strings)
var_name <- quote(y)
f( x, !!var_name )
g( x, !!var_name )
h( x, !!var_name )

# Handling lists of variable names using !!! unquote-splice
# Works with functions that accept dots
arg_names <- rlang::exprs( x, y )
f( !!!arg_names )
h( !!!arg_names )
1 голос
/ 23 сентября 2019

Нам нужно оценить (!!) sym bols

tidyr::expand(dummy,  !!! syms(c('x', 'y')))
# A tibble: 4 x 2
#  x     y    
#  <fct> <fct>
#1 ex1   cat1 
#2 ex1   cat2 
#3 ex2   cat1 
#4 ex2   cat2 

Это будет особенно полезно, когда имена столбцов хранятся в vector и хотят сделать expand

nm1 <- c('x', 'y')
tidyr::expand(dummy, !!! syms(nm1))

В некоторых других комбинациях либо !!!, либо преобразование в sym бол отсутствует в character векторе

...