簡體   English   中英

使用 stringr::str_extract 將參數傳遞給包含 dplyr 管道表達式 group_by 的函數

[英]Pass argument to a function containing dplyr piped expression group_by with stringr::str_extract

我想根據子字符串按組匯總以下數據:

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)
}

雙括號字符串是我的嘗試之一,我首先嘗試沒有,嘗試傳遞引用的名稱等無濟於事。 嘗試在數據集上使用它:

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 沒有看到 DF 中存在的sometext列名稱:

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

通過一些修改,我們可以使用以下代碼。

  1. 我們不需要評估patterns (添加這一點是因為我也想到了tidy eval patterns )。

  2. 我們可以使用{{}}rlang >=0.4.0評估strings

  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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM