Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use dplyr to conditionally change values in a column by group?

Tags:

r

dplyr

I have data like this:

g1 g2 var 
 1  a Yes 
 1  a No 
 1  a No 
 1  b Yes 
 1  b Yes 
 1  b Yes 
 2  a No 
 2  a No 
 2  a No

I would like to change all values in var to Yes if in each g1&g2 group, there is at least one Yes in var. I tried to use combinations of group_by and mutate, replace, ifelse with no success. Any help is appreciated.

like image 209
Bigfoot Avatar asked Oct 19 '25 10:10

Bigfoot


2 Answers

We can use if/else instead of ifelse. Grouped by 'g1', 'g2', if 'Yes' is %in% 'var', then return "Yes" or else return 'var'

library(dplyr)
df1 %>% 
   group_by(g1, g2) %>% 
   mutate(var = if("Yes" %in% var) "Yes" else var)
# A tibble: 9 x 3
# Groups:   g1, g2 [3]
#     g1 g2    var  
#  <int> <chr> <chr>
#1     1 a     Yes  
#2     1 a     Yes  
#3     1 a     Yes  
#4     1 b     Yes  
#5     1 b     Yes  
#6     1 b     Yes  
#7     2 a     No   
#8     2 a     No   
#9     2 a     No   

Or with case_when

df1 %>% 
   group_by(g1, g2) %>% 
   mutate(var = case_when("Yes" %in% var ~ "Yes", TRUE ~ var))

data

df1 <- structure(list(g1 = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L), g2 = c("a", 
 "a", "a", "b", "b", "b", "a", "a", "a"), var = c("Yes", "No", 
 "No", "Yes", "Yes", "Yes", "No", "No", "No")), class = "data.frame", 
  row.names = c(NA, -9L))
like image 148
akrun Avatar answered Oct 21 '25 01:10

akrun


You can also do:

df %>%
 group_by(g1, g2) %>%
 mutate(var = ifelse(any(var == "Yes"), "Yes", "No"))

     g1 g2    var  
  <int> <chr> <chr>
1     1 a     Yes  
2     1 a     Yes  
3     1 a     Yes  
4     1 b     Yes  
5     1 b     Yes  
6     1 b     Yes  
7     2 a     No   
8     2 a     No   
9     2 a     No   

Here, if any value (per "g1" and "g2") in "var" is equal to Yes, it returns Yes, otherwise No.

like image 38
tmfmnk Avatar answered Oct 21 '25 01:10

tmfmnk