将列名输入 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)