sdS
sdS

Reputation: 53

Recode variables using mutate_at where column names very more than one condition

Edit: I actually have text that needs to be recoded. Updated to reflect -- I have a set of variables with labels "js" and other variables with js_R_". I need to recode these two variables independently, meaning all "js" columns need to be recoded with the same rules, but with different rules than "js_R_", and vice versa. Say my data set looks like this:

d1 <- data.frame(js_1 = c("Strongly agree", "Agree", "Neither", "Disagree", "Strongly disagree"), 
                 js_R_2 = c("Strongly disagree", "Disagree", "Neither", "Agree", "Strongly agree"))

                    

What I would like to do is specify recode rules for columns that contain "js" but do NOT contain "_R _". Typically, I would do something like

  mutate_at(
    vars(contains("js"),
    funs(case_when(.== "Strongly disagree"~1,
      .== "Disagree"~2,
      .== "Neither"~3,
      .== "Agree"~4,
      .== "Strongly agree" ~5))) 

but I have been unsuccesful at adding multiple criteria to my vars command.

Any help is appreciated!

Upvotes: 0

Views: 442

Answers (1)

harre
harre

Reputation: 7287

We could also use multiple conditions, continuing with contains():

library(dplyr)

# Using case_when like OP
d1 |>
  mutate(
    across(contains("js") & !contains("R"),
           ~ case_when(. == "Strongly disagree" ~ 1,
                       . == "Disagree" ~ 2,
                       . == "Neither" ~ 3,
                       . == "Agree" ~ 4,
                       . == "Strongly agree" ~ 5))
  )

# Using case_match (recode in dplyr v. < 1.1.0)
d1 |>
  mutate(
    across(contains("js") & !contains("R"),
           ~ case_match(.,
                        "Strongly disagree" ~ 1,
                        "Disagree" ~ 2,
                        "Neither" ~ 3,
                        "Agree" ~ 4,
                        "Strongly agree" ~ 5))
  )

Output:

  js_1            js_R_2
1    5 Strongly disagree
2    4          Disagree
3    3           Neither
4    2             Agree
5    1    Strongly agree

mutate_at etc. is superseded and funs() is deprecated, but if you prefer:

d1 |>
  mutate_at(
            vars(contains("js") & !contains("R")),
                 funs(case_when(. == "Strongly disagree" ~ 1,
                                . == "Disagree" ~ 2,
                                . == "Neither" ~ 3,
                                . == "Agree" ~ 4,
                                . == "Strongly agree" ~ 5))
            )

Upvotes: 2

Related Questions