Передайте аргумент в функцию, содержащую dplyr переданное по трубопроводу выражение group_by с помощью stringr :: str_extract - PullRequest
2 голосов
/ 13 января 2020

Я хотел бы обобщить следующие данные по группам на основе подстрок:

df <- tribble(
  ~sometext, ~somevalue,
  "Kardiochirurgia",  120,
  "Kardiologia",      240,
  "Ortopedia onkologiczna",        120,
  "Kardiochirurgia onkologiczna", 300,
  "Ortopedia i traumatologia",110,
  "Urologia", 80
)

Вот мои подстроки, которые я хотел бы сгруппировать по:

categories <- c("kardio","orto", "uro")

Следующий код работает и я буду использовать его несколько раз, поэтому я хотел бы превратить его в функцию:

df %>% 
  group_by(categories=
    str_extract(
      string = str_to_lower(.$sometext),
      pattern = paste0(categories, collapse="|"))) %>% 
  summarise(somevalue = sum(somevalue))

Скрипт возвращает именно то, что я ожидал:

# # A tibble: 3 x 2
# categories somevalue
# <chr>          <dbl>
# 1 kardio           660
# 2 orto             230
# 3 uro               80

После того, как я превратил его в функция, она не работает:

group_by_str <- function(df, strings, patterns) {
  df %>% 
    group_by(categories=
               str_extract(
                 string = str_to_lower(.[,{{strings}}]),
                 pattern = paste0(patterns, collapse="|"))) 
   return(df)
}

Строка в двойных скобках - одна из моих попыток, я пытался сначала без, пытался передать имя в кавычках et c. но безрезультатно . Попытка использовать его в наборе данных:

df %>% group_by_str(strings=sometext, patterns= categories) %>% summarise(somevalue = sum(somevalue))

возвращает ошибку, очевидно, он не знает, что 'strings' - это имя столбца, содержащего строки. Каким должен быть правильный способ передачи имени столбца в функцию в этом случае?

Сообщение об ошибке указывает, что R может видеть содержимое столбца и пытается рассматривать его как имена столбцов:

 Error: Can't find columns `Kardiochirurgia`, `Kardiologia`, `Ortopedia onkologiczna`, `Kardiochirurgia onkologiczna`, `Ortopedia i traumatologia`, … (and 1 more) in `.data`.
Run `rlang::last_error()` to see where the error occurred. 

Если я уберу фигурные скобки, ошибка говорит о том, что R не видит имя столбца sometext в DF:

Error in check_names_df(j, x) : object 'sometext' not found

1 Ответ

4 голосов
/ 13 января 2020

С некоторыми модификациями мы можем использовать следующий код.

  1. Нам не нужно оценивать patterns (добавил этот пункт, потому что я думал о tidy eval также patterns).

  2. Мы можем оценить strings с {{}} с rlang > = 0,4,0 .

  3. Нам не нужно return утверждение

  4. Мы можем делать все (включая суммирование) внутри нашей функции

Модифицированный код:

group_by_str <- function(df, strings, patterns) {
  df %>% 
    group_by(categories=
               str_extract(
                 string = str_to_lower({{strings}}),
                 pattern = paste0(patterns, 
                                          collapse="|"))) %>%

    summarise(somevalue = sum(somevalue)) 

} 


  group_by_str(df,strings=sometext, patterns= categories) 

Труба дружелюбна:

 df %>% 
  group_by_str(strings=sometext, patterns= categories)

Результат:

# A tibble: 3 x 2
  categories somevalue
  <chr>          <dbl>
1 kardio           660
2 orto             230
3 uro               80
...