将列名输入 purrr::map 用于用户函数时,整洁 select 出错
Error with tidy select when feeding column names into purrr::map for user function
我有一个很长的函数,它使用一个数据框列名作为输入,我试图将它应用于几个不同的列名,每次都没有新的代码行。我在 map 调用的函数中遇到 tidyselect 问题。我相信这个问题与化解有关,但我无法弄清楚。下面是一个使用 mtcars 数据的玩具示例。
这适用于地图:
library(tidyverse)
sum_dplyr <- function(df, x) {
res <- df %>% summarise(mean = mean({{x}}, na.rm = TRUE))
return(res)
}
sum_dplyr(mtcars, disp)
map(names(mtcars), ~ sum_dplyr(mtcars, mtcars[[.]])) # all columns -> works fine
虽然在通过 map 馈送函数时出现错误“必须使用有效的下标向量对列进行子集化”:
library(tidyverse)
sel_dplyr <- function(df, x) {
res <- df %>% dplyr::select({{x}})
return(res)
}
sel_dplyr(mtcars, disp) # ok
map(names(mtcars), ~ sel_dplyr(mtcars, mtcars[[.]])) # all columns -> error
我在这里错过了什么?非常感谢!
最好更正函数以确保它既接受未引用又接受引用。使用 map
,我们正在传递一个字符串。因此,可以将 ensym
与 !!
一起使用,而不是 {{}}
sum_dplyr <- function(df, x) {
x <- rlang::ensym(x)
res <- df %>%
summarise(mean = mean(!!x, na.rm = TRUE))
return(res)
}
同样适用于 sel_dplyr
sel_dplyr <- function(df, x) {
x <- rlang::ensym(x)
res <- df %>%
dplyr::select(!! x)
return(res)
}
然后测试为
library(purrr)
library(dplyr)
map(names(mtcars), ~ sel_dplyr(mtcars, !!.x))
sel_dplyr(mtcars, carb)
我有一个很长的函数,它使用一个数据框列名作为输入,我试图将它应用于几个不同的列名,每次都没有新的代码行。我在 map 调用的函数中遇到 tidyselect 问题。我相信这个问题与化解有关,但我无法弄清楚。下面是一个使用 mtcars 数据的玩具示例。
这适用于地图:
library(tidyverse)
sum_dplyr <- function(df, x) {
res <- df %>% summarise(mean = mean({{x}}, na.rm = TRUE))
return(res)
}
sum_dplyr(mtcars, disp)
map(names(mtcars), ~ sum_dplyr(mtcars, mtcars[[.]])) # all columns -> works fine
虽然在通过 map 馈送函数时出现错误“必须使用有效的下标向量对列进行子集化”:
library(tidyverse)
sel_dplyr <- function(df, x) {
res <- df %>% dplyr::select({{x}})
return(res)
}
sel_dplyr(mtcars, disp) # ok
map(names(mtcars), ~ sel_dplyr(mtcars, mtcars[[.]])) # all columns -> error
我在这里错过了什么?非常感谢!
最好更正函数以确保它既接受未引用又接受引用。使用 map
,我们正在传递一个字符串。因此,可以将 ensym
与 !!
{{}}
sum_dplyr <- function(df, x) {
x <- rlang::ensym(x)
res <- df %>%
summarise(mean = mean(!!x, na.rm = TRUE))
return(res)
}
同样适用于 sel_dplyr
sel_dplyr <- function(df, x) {
x <- rlang::ensym(x)
res <- df %>%
dplyr::select(!! x)
return(res)
}
然后测试为
library(purrr)
library(dplyr)
map(names(mtcars), ~ sel_dplyr(mtcars, !!.x))
sel_dplyr(mtcars, carb)