将参数传递给包含 dplyr 管道表达式 group_by 和 stringr::str_extract 的函数
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))
脚本 returns 完全符合我的预期:
# # 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))
returns一个错误,显然它不知道'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
经过一些修改,我们可以使用下面的代码。
我们不需要评估patterns
(添加这一点是因为我也想到了tidy
eval
uating patterns
)。
我们可以用{{}}
和rlang
计算strings
>=0.4.0。
我们不需要 return
声明
我们可以在我们的函数中做任何事情(包括总结)
修改后的代码:
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
我想根据子字符串分组总结以下数据:
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))
脚本 returns 完全符合我的预期:
# # 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))
returns一个错误,显然它不知道'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
经过一些修改,我们可以使用下面的代码。
我们不需要评估
patterns
(添加这一点是因为我也想到了tidy
eval
uatingpatterns
)。我们可以用
{{}}
和rlang
计算strings
>=0.4.0。我们不需要
return
声明我们可以在我们的函数中做任何事情(包括总结)
修改后的代码:
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