首页 > 解决方案 > 在 R 中重新编码除一个变量外的所有变量

问题描述

我正在尝试在函数内的列中重新编码除一种类型的元素之外的所有元素。列名会根据函数的输入而变化,并且列中不应重新编码的元素也会根据函数输入而变化。

数据框(代码片段中的 df)如下所示:

... 教育 ...
... 学士 ...
... 掌握 ...
... 中学 ...
... 中学 ...
... 掌握 ...

但也可能看起来像

... 性别 ...
... 男性 ...
... 女性 ...
... 女性 ...
... 女性 ...
... 男性 ...

我想要的输出分别如下:

... 教育 ...
... 学士 ...
... 休息 ...
... 休息 ...
... 休息 ...
... 休息 ...
... 性别 ...
... 男性 ...
... 休息 ...
... 休息 ...
... 休息 ...
... 男性 ...

我尝试了以下方法:

select_data <- function(df, col_name, do_not_change){
     df <- df %>%
       dplyr::mutate('{col_name}' = recode(col_name, '{do_not_change}' := {{do_not_change}}, .default = "rest"))

所以调用将分别如下所示:

# case of education
education_df <- function(df, education, 'bachelor')
# case of gender
gender_df <- function(df, gender, 'male')

但是,这似乎不起作用。任何帮助将不胜感激。提前致谢!

标签: rdplyr

解决方案


函数可以修改为

select_data <- function(df, col_name, do_not_change){
     df %>%
       dplyr::mutate({{col_name}} := recode({{col_name}}, 
           {{do_not_change}} := {{do_not_change}}, .default = "rest"))
      
       }

并称为

select_data(df, gender, 'male')  
  gender   education
1   male    bachelor
2   rest      master
3   rest high school
4   male      master 

如果我们需要传递一个字符串,使用ensym可以同时处理带引号/不带引号的输入

select_data <- function(df, col_name, do_not_change){
   col_name <- rlang::ensym(col_name)
     df %>%
       dplyr::mutate({{col_name}} := recode(!! col_name, 
           {{do_not_change}} := {{do_not_change}}, .default = "rest"))
      
       }

-测试

> select_data(df, 'gender', 'male') 
  gender   education
1   male    bachelor
2   rest      master
3   rest high school
4   male      master
> select_data(df, gender, 'male')
  gender   education
1   male    bachelor
2   rest      master
3   rest high school
4   male      master

如果我们将两个参数作为带引号或不带引号的形式传递

select_data <- function(df, col_name, do_not_change){
   col_name <- rlang::ensym(col_name)
   do_not_change <- rlang::as_string(rlang::ensym(do_not_change))
     df %>%
       dplyr::mutate({{col_name}} := recode(!! col_name, 
           {{do_not_change}} := {{do_not_change}}, .default = "rest"))
      
       }

-测试

> select_data(df, 'gender', 'male') 
  gender   education
1   male    bachelor
2   rest      master
3   rest high school
4   male      master
> select_data(df, gender, male)
  gender   education
1   male    bachelor
2   rest      master
3   rest high school
4   male      master

数据

df <- structure(list(gender = c("male", "female", "female", "male"), 
    education = c("bachelor", "master", "high school", "master"
    )), row.names = c(NA, -4L), class = "data.frame")

推荐阅读