3
votes

I would like to fill a column conditionally using dplyr::mutate. One level of the new variable should correspond to if a value was present at all in the previous column and the other level is an 'else' condition.

I have a dataframe:

         group     piece      answer         agreement
        group1     A          noise       good 
        group1     A          silence     good
        group1     A          silence     good
        group1     B          silence     bad
        group1     B          loud_noise  bad
        group1     B          noise       bad
        group1     B          loud_noise  bad
        group1     B          noise       bad
        group2     C          silence     good
        group2     C          silence     good

I want to create a new variable grouping by group where if 'bad' appears in 'agreement', then the value should be 'inconsistent' but if all of the values of 'agreement' are 'good', then the value should be 'consistent.'

        group     piece      answer     agreement   new_agreement
        group1     A          noise       good       bad
        group1     A          silence     good       bad
        group1     A          silence     good       bad
        group1     B          silence     bad        bad
        group1     B          loud_noise  bad        bad
        group1     B          noise       bad        bad
        group1     B          loud_noise  bad        bad
        group1     B          noise       bad        bad
        group2     C          silence     good       good
        group2     C          silence     good       good

But case_when doesn't quite do that - it's just copying the same variable over again:

   newdf <- df %>%
    group_by(group) %>%
    mutate(new_agreement = case_when(agreement == 'bad' ~
    "inconsistent", agreement =='good' ~ "consistent")) %>%
    as.data.frame()
2
Your new column does not match your problem description. Could you please edit the question?Rui Barradas

2 Answers

3
votes

Just add any(agreement == 'bad')

df %>%
  group_by(group) %>%
  mutate(new_agreement = case_when(any(agreement == 'bad') ~"inconsistent",
                                   agreement =='good' ~ "consistent"))
    # A tibble: 10 x 5
    # Groups:   group [2]
       group  piece answer     agreement new_agreement
       <fct>  <fct> <fct>      <fct>     <chr>        
     1 group1 A     noise      good      inconsistent 
     2 group1 A     silence    good      inconsistent 
     3 group1 A     silence    good      inconsistent 
     4 group1 B     silence    bad       inconsistent 
     5 group1 B     loud_noise bad       inconsistent 
     6 group1 B     noise      bad       inconsistent 
     7 group1 B     loud_noise bad       inconsistent 
     8 group1 B     noise      bad       inconsistent 
     9 group2 C     silence    good      consistent   
    10 group2 C     silence    good      consistent   

You can even use if_else with any:

df %>% 
  group_by(group) %>% 
  mutate(new_agreement= if_else(any(agreement=="bad"), "inconsistent", "consistent") )
0
votes

With case_when, use any.

library(dplyr)

df %>%
  group_by(group) %>%
  mutate(new_agreement = case_when(
    any(agreement == 'bad') ~ 'inconsistent',
    TRUE ~ 'consistent'))
## A tibble: 10 x 5
## Groups:   group [2]
#   group  piece answer     agreement new_agreement
#   <fct>  <fct> <fct>      <fct>     <chr>        
# 1 group1 A     noise      good      inconsistent 
# 2 group1 A     silence    good      inconsistent 
# 3 group1 A     silence    good      inconsistent 
# 4 group1 B     silence    bad       inconsistent 
# 5 group1 B     loud_noise bad       inconsistent 
# 6 group1 B     noise      bad       inconsistent 
# 7 group1 B     loud_noise bad       inconsistent 
# 8 group1 B     noise      bad       inconsistent 
# 9 group2 C     silence    good      consistent   
#10 group2 C     silence    good      consistent   

Data in dput format.

df <-
structure(list(group = structure(c(1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 2L, 2L), .Label = c("group1", "group2"), 
class = "factor"), piece = structure(c(1L, 1L, 1L, 2L, 
2L, 2L, 2L, 2L, 3L, 3L), .Label = c("A", "B", "C"), 
class = "factor"), answer = structure(c(2L, 3L, 3L, 
3L, 1L, 2L, 1L, 2L, 3L, 3L), .Label = c("loud_noise", 
"noise", "silence"), class = "factor"), agreement = 
structure(c(2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 2L, 2L), 
.Label = c("bad", "good"), class = "factor")), 
class = "data.frame", row.names = c(NA, -10L))