How can I make this mutation into a function?

65 views Asked by At

I have a bunch of variables, where I have these alternative text answers. Some of these alternative answers correspond to an answer in the multiple choice selection, so all I want to do is to recode these values back to the numerical format. I made a code that works:

s1 <- s1 %>%
  mutate(s1_auto1_eigendom = coalesce(case_when(
    s1_auto1_eigendom_anderstext == 'alleen ik' ~ 1,
    s1_auto1_eigendom_anderstext == 'Alleen van mij' ~ 1,
    s1_auto1_eigendom_anderstext == 'echtpaar' ~ 1,
    s1_auto1_eigendom_anderstext == 'eigen auto' ~ 1,
    s1_auto1_eigendom_anderstext == 'lease auto partner via zijn werkgever' ~ 2,
    s1_auto1_eigendom_anderstext == 'Lease auto van mijn partner' ~ 3,
    s1_auto1_eigendom_anderstext == 'mij' ~ 1,
    s1_auto1_eigendom_anderstext == 'Mij' ~ 1,
    s1_auto1_eigendom_anderstext == 'mij zelf' ~ 1,
    s1_auto1_eigendom_anderstext == 'Mijn eigen auto' ~ 1,
    s1_auto1_eigendom_anderstext == 'mijzelf' ~ 1,
    s1_auto1_eigendom_anderstext == 'Mijzelf' ~ 1,
    s1_auto1_eigendom_anderstext == 'van 1e pers.' ~ 1,
    s1_auto1_eigendom_anderstext == 'van mij' ~ 1,
    s1_auto1_eigendom_anderstext == 'Van mij' ~ 1,
    s1_auto1_eigendom_anderstext == 'van mij alleen' ~ 1,
    s1_auto1_eigendom_anderstext == 'Van mij alleen' ~ 1,
    s1_auto1_eigendom_anderstext == 'van mij alleen.' ~ 1,
    s1_auto1_eigendom_anderstext == 'van mij dus' ~ 1,
    s1_auto1_eigendom_anderstext == 'van mij en 1 lid van mijn huishouden' ~ 1,
    s1_auto1_eigendom_anderstext == 'van mijzelf' ~ 1,
    s1_auto1_eigendom_anderstext == 'Van mijzelf' ~ 1,
    s1_auto1_eigendom_anderstext == 'van ons samen' ~ 1,
    s1_auto1_eigendom_anderstext == 'Van ons samen ' ~ 1), s1_auto1_eigendom))
s1 <- s1 %>%
  mutate(s1_auto1_eigendom_anderstext = case_when(s1_auto1_eigendom != 7 ~ NA))

But I have 8 more variables, where I have to do this exact same thing for. I have to do this same thing also for s1_auto2_eigendom, s1_auto3_eigendom, ... s1_auto8_eigendom, so I thought I would condense it a bit by making a function.

I tried this:

recode_s1_autox_eigendom <- function(x,y) {
  mutate(x = coalesce(case_when(
      y == 'alleen ik' ~ 1,
      y == 'Alleen van mij' ~ 1,
      y == 'echtpaar' ~ 1,
      y == 'eigen auto' ~ 1,
      y == 'lease auto partner via zijn werkgever' ~ 2,
      y == 'Lease auto van mijn partner' ~ 3,
      y == 'mij' ~ 1,
      y == 'Mij' ~ 1,
      y == 'mij zelf' ~ 1,
      y == 'Mijn eigen auto' ~ 1,
      y == 'mijzelf' ~ 1,
      y == 'Mijzelf' ~ 1,
      y == 'van 1e pers.' ~ 1,
      y == 'van mij' ~ 1,
      y == 'Van mij' ~ 1,
      y == 'van mij alleen' ~ 1,
      y == 'Van mij alleen' ~ 1,
      y == 'van mij alleen.' ~ 1,
      y == 'van mij dus' ~ 1,
      y == 'van mij en 1 lid van mijn huishouden' ~ 1,
      y == 'van mijzelf' ~ 1,
      y == 'Van mijzelf' ~ 1,
      y == 'van ons samen' ~ 1,
      y == 'Van ons samen ' ~ 1), x))
  mutate(y = case_when(x != 7 ~ NA))
}
s1 <- recode_s1_autox_eigendom(s1$s1_auto1_eigendom,s1$s1_auto1_eigendom_anderstext)

But nothing happens when I do that. No error, but I don't get any result. I tried first having the piped option and then I tried having the s1 <- in front of the code inside the function, and that also did not work.

To explain a bit the data, s1_auto1_eigendom takes values 1-7 and 7 indicates "anders" and for many answers 7, there will be a text entry in s1_auto1_eigendom_anderstext and some of these text entries correspond to other values than 7.

Example:

col1     col2     col3     col4 ....
1                 1
2                 4
7       "mij"     5        
3               
4                 4
7       "mijzelf" 7        "mij"
7       "other" 
7       "other"   7        "other"

To

col1     col2     col3     col4 ....
1                 1
2                 4
1                 5        
3               
4                 4
1                 1        
7       "other" 
7       "smthng"  7        "other"
1

There are 1 answers

5
Ronak Shah On

When you are comparing multiple values use %in% instead of ==.

For eg -

Instead of doing this -

library(dplyr)

x <- 1:4

case_when(x == 1 ~ '1', 
          x == 2 ~ '1', 
          x == 3 ~ '2')

#[1] "1" "1" "2" NA 

Do this -

case_when(x %in% c(1, 2) ~ '1',
          x == 3 ~ '2')
#[1] "1" "1" "2" NA 

Secondly, use across to apply a function to multiple columns.

fun <- function(x) {
  case_when(x %in% c(1, 2) ~ '1',
            x == 3 ~ '2')
}

df <- data.frame(a = 1:4, b = 4:1)

df %>% mutate(across(c(a, b), fun))

#     a    b
#1    1 <NA>
#2    1    2
#3    2    1
#4 <NA>    1