Смешанный ввод в квазиквотации с dplyr

Я взял квази-цитату на высший уровень. Я близок к получению своего мастер-квазиквотатора (см. правки ниже). Остался один бит с челленджем.

Использование разных входов для создания предложений с помощью dplyr. Конечный результат:

the_quote <- quo( if_else(!!cond_expr, !!inter_quo, !!var_expr) )

И мне удалось построить выражения выше из настраиваемой таблицы с символьными строками, как это:

var_expr <- as.name(rules_df$target_col)

cond_expr <- "make == '%s'" %>% sprintf(rules_df$context_col) %>% parse_expr()

inter_quo <- quo( 
    str_detect( !!var_expr, regex(!!rules_df$phrase_col) ))

И где context_col, phrase_col, target_col Строковые столбцы в таблице, которые я определил правила участия.

Пример:

rules_df <- data_frame(
    context_col = "BMW", 
    phrase_col  = "Serie X(\\d)", 
    target_col  = "model")

cars_table <- data_frame(
    make = c("Mercedes", "BMW", "BMW"), 
    model = c("Viano", "Serie X5", "Z4"))

Говорит мне, чтобы найти эти BMW как Serie X5, который я позже заменил бы просто X5 но это другая история.

При печати цитаты я заметил, что выражения работают хорошо, но промежуточное выражение дает ошибку.

> the_quote
<quosure>
  expr: ^if_else(marca == "BMW", 
            ^str_detect(model, regex("Serie X(\d)")), model)
  env:  000000002001DEE0

> mutate(cars_table, detect = !!the_quote)
Error: Evaluation error: `false` must be type logical, not character.

В деле у меня есть дополнительный ^ который преобразует результат str_detect в символ.

Как интегрировать это промежуточное предложение во внешнее?

Благодарю.

редактировать

После рассмотрения решения выясняется, что проблема в этой задаче заключалась не в предложении, а в использовании if_else правильно в detect колонка. Это меняет логический характер или просто действует ложное предложение.

Таким образом, альтернативное решение состоит в том, чтобы установить if_else(!!cond_expr, !!inter_quo, FALSE) с начала.

1 ответ

Решение

Нам нужно обернуть as.character как str_detect возвращает логический класс, в то время как false параметр if_else возвращает "характер". if_else особенно о классе. Таким образом, если мы делаем

inter_quo <- quo( as.character(str_detect( !!var_expr, 
               regex(!!rules_df$phrase_col) )))

тогда должно работать

mutate(cars_table, detect = !!the_quote)
# A tibble: 3 x 3
#  make     model    detect
#  <chr>    <chr>    <chr> 
#1 Mercedes Viano    Viano 
#2 BMW      Serie X5 TRUE  
#3 BMW      Z4       FALSE 
Другие вопросы по тегам