r - 使用 enquo() 以 dplyr 语法编写可管道函数,不返回预期的输出
问题描述
library(tidyverse)
library(stringr)
library(janitor)
word_count <- function(data, char_col) {
char_col <- enquo(char_col)
data %>%
select(!!char_col) %>%
mutate(char_col = str_remove_all(!!char_col, '[[:punct:]]')) %>%
mutate(char_col = str_split(!!char_col, ' ')) %>%
separate(char_col, into = paste0('col', 1:30), fill = 'right') %>%
select(-col1) %>%
gather(value = word) %>%
select(word) %>%
remove_empty(c('rows')) %>%
filter(word != '') %>%
mutate(word = str_to_lower(word)) %>%
group_by(word) %>%
summarize(freq = n()) %>%
arrange(desc(freq))
}
iris %>%
as.tibble() %>%
mutate(Species = str_c(Species, ' species')) %>%
word_count(Species)
此代码在函数外部按预期工作,但是当我在函数内部使用它时,它将返回每个单词和每个“非拆分”字符串的频率。
我认为这是我如何放置“!!”的问题 运营商,但我无法通过与他们进行反复试验来解决这个问题。这也可能是一个lazyeval问题,我不确定如何解决。
我希望函数的输出与下面代码的输出相匹配。
iris %>%
as.tibble() %>%
mutate(Species = str_c(Species, ' species')) %>%
select(Species) %>%
mutate(Species = str_remove_all(Species, '[[:punct:]]')) %>%
mutate(Species = str_split(Species, ' ')) %>%
separate(Species, into = paste0('col', 1:30), fill = 'right') %>%
select(-col1) %>%
gather(value = word) %>%
select(word) %>%
remove_empty(c('rows')) %>%
filter(word != '') %>%
mutate(word = str_to_lower(word)) %>%
group_by(word) %>%
summarize(freq = n()) %>%
arrange(desc(freq))
解决方案
我们不能将char_col
对象作为列名分配给mutate
. 它需要被评估。这char_col
是一个quosure
可以转换为character
( quo_name(char_col)
) 的对象,或者symbol
在评估时 ( !!
) 将分配 ( :=
) 正确的列名
word_count <- function(data, char_col) {
char_col <- enquo(char_col)
char_colC <- quo_name(char_col)
data %>%
select(!!char_col) %>%
mutate(!!char_colC := str_remove_all(!!char_col, '[[:punct:]]')) %>%
mutate(!!char_colC := str_split(!!char_col, ' ')) %>%
separate(char_colC, into = paste0('col', 1:30), fill = 'right') %>%
select(-col1) %>%
gather(value = word) %>%
select(word) %>%
remove_empty(c('rows')) %>%
filter(word != '') %>%
mutate(word = str_to_lower(word)) %>%
group_by(word) %>%
summarize(freq = n()) %>%
arrange(desc(freq))
}
out2 <- iris %>%
as.tibble() %>%
mutate(Species =str_c(Species, ' species')) %>%
word_count(Species)
- 在不使用函数的情况下检查输出
out1 <- iris %>%
as.tibble() %>%
mutate(Species = str_c(Species, ' species')) %>%
select(Species) %>%
mutate(Species = str_remove_all(Species, '[[:punct:]]')) %>%
mutate(Species = str_split(Species, ' ')) %>%
separate(Species, into = paste0('col', 1:30), fill = 'right') %>%
select(-col1) %>%
gather(value = word) %>%
select(word) %>%
remove_empty(c('rows')) %>%
filter(word != '') %>%
mutate(word = str_to_lower(word)) %>%
group_by(word) %>%
summarize(freq = n()) %>%
arrange(desc(freq))
identical(out1, out2)
#[1] TRUE
推荐阅读
- python - 无法使用 FastAPI 处理范围内的日期范围
- c++ - 带有向量和类的函数指针
- nestjs - 如何配置本地包以在 NestJS 应用程序中使用?
- laravel - 在 Blade 中包含 HTML
- github - 在 actions/checkout@v2 中使用 env 变量作为 ref
- node.js - 从 .foreach 中获取 var
- android - Play store 无效的 apk 签名颤动(APK 完整性检查失败)
- jquery - 模态表单下拉菜单未设置值 PHP & Jquery Ajax
- api - “消息”:“无法处理有效载荷”邮递员
- android - FutureBuilder snapshot.data 在 http 调用之前被设置为 null