More efficient way for modifying values across multiple lines with dplyr

Viewed 200

After learning the basics of data transformation in R, I'm practising now on a a dataset. I do have four variables with the same values and I want to modify the numeric values into character strings. I found the function case_when() on this website and applied that to each column, but I would really like to do that faster.

The data looks like that:

 climate_change air_quality water_polution trash
            <dbl>       <dbl>          <dbl> <dbl>
 1              3           2              2     1
 2              3           3              3     3
 3             NA          NA             NA    NA
 4             NA          NA             NA    NA
 5              1           1              1     1
 6              2           1              4     2
 7              2           3              3     2
 8             NA          NA             NA    NA
 9              3           3              2     2
10             NA          NA             NA    NA

And I used this code:

dataset <- dataset %>%
  mutate(climate_change = case_when(
    climate_change %in% c(1) ~ "A very serious problem",
    climate_change %in% c(2) ~ "A somewhat serious problem",
    climate_change %in% c(3) ~ "Not a very serious problem",
    climate_change %in% c(4) ~ "Not at all a serious problem"),
    air_quality = case_when(
      air_quality %in% c(1) ~ "A very serious problem",
      air_quality %in% c(2) ~ "A somewhat serious problem",
      air_quality %in% c(3) ~ "Not a very serious problem",
      air_quality %in% c(4) ~ "Not at all a serious problem"),
    water_polution = case_when(
      water_polution %in% c(1) ~ "A very serious problem",
      water_polution %in% c(2) ~ "A somewhat serious problem",
      water_polution %in% c(3) ~ "Not a very serious problem",
      water_polution %in% c(4) ~ "Not at all a serious problem"),
    trash = case_when(
      trash %in% c(1) ~ "A very serious problem",
      trash %in% c(2) ~ "A somewhat serious problem",
      trash %in% c(3) ~ "Not a very serious problem",
      trash %in% c(4) ~ "Not at all a serious problem"))

In addition to the four values (1-4) these variables have two types of missing values (88, 99). I have left out the missing values in the case_when() function as these seem to be coded into NA automatically. But are there any downsides in not specifically code these values into NA?

Greetings

2 Answers

To apply the same function to multiple columns you can use across in new dplyr.

If there is only one value for one number you can use recode

library(dplyr)

dataset %>%
  mutate(across(climate_change:trash, 
                #use everything() if you want to do it for all the columns
                ~recode(., `1` = "A very serious problem",
                           `2` = "A somewhat serious problem",
                           `3` = "Not a very serious problem",
                           `4` = "Not at all a serious problem")))

Similarly, using case_when :

dataset %>%
   mutate(across(climate_change:trash, 
                ~case_when(. == 1 ~ "A very serious problem",
                           . == 2 ~ "A somewhat serious problem",
                           . == 3 ~ "Not a very serious problem",
                           . == 4 ~"Not at all a serious problem")))

In old dplyr you can use mutate_at :

dataset %>%
   mutate_at(vars(climate_change:trash), ~case_when....
                                          #same code
   #Use mutate_all if you want to do it for all the columns.

We can do this with a named vector

library(dplyr)
v1 <- setNames(c("A very serious problem","A somewhat serious problem",
     "Not a very serious problem", "Not at all a serious problem"), 1:4)
dataset %>%
   mutate(across(climate_change:trash, ~ v1[as.character(.x)]))
#             climate_change                air_quality               water_polution                      trash
#1  Not a very serious problem A somewhat serious problem   A somewhat serious problem     A very serious problem
#2  Not a very serious problem Not a very serious problem   Not a very serious problem Not a very serious problem
#3                        <NA>                       <NA>                         <NA>                       <NA>
#4                        <NA>                       <NA>                         <NA>                       <NA>
#5      A very serious problem     A very serious problem       A very serious problem     A very serious problem
#6  A somewhat serious problem     A very serious problem Not at all a serious problem A somewhat serious problem
#7  A somewhat serious problem Not a very serious problem   Not a very serious problem A somewhat serious problem
#8                        <NA>                       <NA>                         <NA>                       <NA>
#9  Not a very serious problem Not a very serious problem   A somewhat serious problem A somewhat serious problem
#10                       <NA>                       <NA>                         <NA>                       <NA>
Related