列名上的整洁评估映射

tidy eval map over column names

我自己做了如下功能:

    emp_term_var <- function(data, colName, year = "2015") {
  
  # Terminations by year and variable in df
  colName <- enquo(colName) 
  term_test <- data %>%
    filter(year(DateofTermination) == year) %>%
    group_by(UQ(colName)) %>%
    count(UQ(colName)) %>%
    clean_names()
  return(term_test)
  
}

我有一个包含多个列的 df,例如 Department、State、Position 等。当我想使用我编写的函数时,我将不带引号的列名称放在如下位置:

emp_term_var(data = df, colName = Department, year = "2015")

哪个returns:

# A tibble: 5 x 2
# Groups:   department [5]
  department               n
  <chr>                <int>
1 Admin Offices            1
2 IT/IS                    4
3 Production              15
4 Sales                    1
5 Software Engineering     2
> 

如何映射多个列?如果我尝试

columns <- c(Department, State)

R 不告诉我,因为它将这些标识为对象而不是列名。我怎样才能让 R 知道这些是要存储在对象列中的列名,以便我可以将它传递给以这种形式映射:

map(colnames, ~ emp_term_var(df, colName = .x, year = "2015"))

而不是使用 enquo 将其更改为 .data 或使用 ensym 转换为符号并计算 (!!)

emp_term_var <- function(data, colName, year = "2015") {
  
  # Terminations by year and variable in df
  colName <- ensym(colName) 
  term_test <- data %>%
    filter(year(DateofTermination) == year) %>%
    #group_by(!!colName)) %>%
    count(!!(colName)) %>%
    clean_names()
  return(term_test)
  
}

注意:count 也可以采用不带任何分组的列

ensym 路由的优点是它既可以引用也可以不引用输入,即它将字符串作为列名并且不带引号

nm1 <- c("Department", "State")
purrr::map(nm1, ~ emp_term_var(df, colName = !!.x, year = "2015"))

或者如果我们想使用

emp_term_var(data = df, colName = Department, year = "2015")

或可以服用

emp_term_var(data = df, colName = "Department", year = "2015")

另一个解决方案是保持你的函数不变,但改变你在内部调用它的方式 map():

columns <- c("Department", "State")

map(colnames, ~ emp_term_var(df, colName = .data[[.x]], year = "2015"))

注意我们如何传递 colName = .data[[.x]] 而不是 colName = .x

您也可以在其他情况下执行此操作,例如 for 循环:

for (col in columns) {
  print(
    emp_term_var(df, colName = .data[[col]], year = "2015")
  )
}