Creating a function which mutates two column variables for columns with the same number ID

Viewed 55

I have a data frame:

ID <- c(1:10)
act1_144 <- c("Bedroom", "Bedroom", "Bedroom", "Lounge", "Kitchen", "Bedroom", "Bedroom", "Bedroom", "Lounge", "Kitchen")
wher_144 <- c("Home", "Home", "Home", "Home", "Home", "Home", "Home", "Home", "Home", "Home")
data <- data.frame(ID, act1_144, wher_144)

and I am using mutate to make a new column based on the conditions of two other columns, e.g.

library(dplyr)
data <- data %>%
    mutate(new_144 = case_when(
      act1_144 == "Bedroom" & wher_144 == "Home" ~ "Bedroom",
      act1_144 == "Kitchen" & wher_144 == "Home" ~ "Kitchen",
      act1_144 == "Lounge" & wher_144 == "Home" ~ "Lounge",
      act1_144 == "Bathroom" & wher_144 == "Home" ~ "Bathroom"))

My real data frame has the variables act1_1 - act1_144 and wher_1 - wher_144. I'd like to put the above code into a function to loop through all matching combinations of act1_** and wher_**, as in the example above, without having to rerun the code 144 times.

Is this possible? Thank you in advance

3 Answers

We can use dplyr with num_range and purrr with map2:

library(dplyr)
library(purrr)

data %>% mutate(new_144 = map2(across(num_range(prefix = 'act1_', range = 144)),
                         across(num_range(prefix = 'wher_', range = 144)),
                         ~case_when(
                           .x == "Bedroom" & .y == "Home" ~ "Bedroom",
                           .x == "Kitchen" & .y == "Home" ~ "Kitchen",
                           .x == "Lounge" & .y == "Home" ~ "Lounge",
                           .x == "Bathroom" & .y == "Home" ~ "Bathroom"))%>%
                  flatten)

   ID act1_144 wher_144 new_144
1   1  Bedroom     Home Bedroom
2   2  Bedroom     Home Bedroom
3   3  Bedroom     Home Bedroom
4   4   Lounge     Home  Lounge
5   5  Kitchen     Home Kitchen
6   6  Bedroom     Home Bedroom
7   7  Bedroom     Home Bedroom
8   8  Bedroom     Home Bedroom
9   9   Lounge     Home  Lounge
10 10  Kitchen     Home Kitchen

Here is an idea without loop. You can adapt this to your real dataframe by changing col index.

ID <- c(1:10)
act1_144 <- c("Bedroom", "Bedroom", "Bedroom", "Lounge", "Kitchen", "Bedroom", "Bedroom", "Bedroom", "Lounge", "Kitchen")
wher_144 <- c("Home", "Home", "Home", "Home", "Home", "Home", "Home", "Home", "Home", "Home")
data <- data.frame(ID, act1_144, wher_144)

data2 <- data %>%
  pivot_longer(cols = c(2,3), names_to = "info", values_to = "value") %>% 
  separate(info, "_", into = c("names", "number")) %>% 
  pivot_wider(names_from = names, values_from = value) %>% 
  mutate(new = case_when(
    act1 == "Bedroom" & wher == "Home" ~ "Bedroom",
    act1 == "Kitchen" & wher == "Home" ~ "Kitchen",
    act1 == "Lounge" & wher == "Home" ~ "Lounge",
    act1 == "Bathroom" & wher == "Home" ~ "Bathroom"))

Yet another solution:

library(tidyverse)

ID <- c(1:10)
act1_144 <- c("Bedroom", "Bedroom", "Bedroom", "Lounge", "Kitchen", "Bedroom", "Bedroom", "Bedroom", "Lounge", "Kitchen")
wher_144 <- c("Home", "Home", "Home", "Home", "Home", "Home", "Home", "Home", "Home", "Home")
data <- data.frame(ID, act1_144, wher_144)

data %>% 
  mutate(
    across(
      starts_with("act1_"),
      ~ ifelse(
        cur_data() %>% 
          pull(str_replace(cur_column(),'act1','wher')) == "Home", ., NA),
      .names = "{str_replace(.col,'act1','new')}"))

#>    ID act1_144 wher_144 new_144
#> 1   1  Bedroom     Home Bedroom
#> 2   2  Bedroom     Home Bedroom
#> 3   3  Bedroom     Home Bedroom
#> 4   4   Lounge     Home  Lounge
#> 5   5  Kitchen     Home Kitchen
#> 6   6  Bedroom     Home Bedroom
#> 7   7  Bedroom     Home Bedroom
#> 8   8  Bedroom     Home Bedroom
#> 9   9   Lounge     Home  Lounge
#> 10 10  Kitchen     Home Kitchen
Related