Search code examples
rgrouping

Assigning logical values to all members of the same group in R through a condition


I have the following data frame:

families <- data.frame(family=c('1', '1', '1', '2', '2', '3', '3'),
                             name=c('John', 'Anitta', 'Steven', 'Stella', 'Robert', 'Adam', 'William'),
                             role=c('Leader', 'Partner', 'Son', 'Leader', 'Son', 'Leader', 'Partner'))
print(families)

# A tibble: 7 × 3
# Groups:   family [3]
  family name    role   
  <chr>  <chr>   <chr>  
1 1      John    Leader 
2 1      Anitta  Partner
3 1      Steven  Son    
4 2      Stella  Leader 
5 2      Robert  Son    
6 3      Adam    Leader 
7 3      William Partner

What I want to create is a variable called "couple" which will assign a TRUE or FALSE value to all members of the same family if the presence of a family member with the role "Partner" is detected. I'm hoping it would look something like this:

  family    name    role couple
1      1    John  Leader   TRUE
2      1  Anitta Partner   TRUE
3      1  Steven     Son   TRUE
4      2  Stella  Leader  FALSE
5      2  Robert     Son  FALSE
6      3    Adam  Leader   TRUE
7      3 William Partner   TRUE

I have tried using the group_by() function followed by the mutate() and case_when() functions to achieve this but I've got this result instead:

families <- families %>% 
  group_by(family)

families <- families %>% 
  mutate(
    couple = case_when(
      role == 'Partner' ~ TRUE,
      TRUE ~ FALSE
    )
  )

print(families)

# A tibble: 7 × 4
# Groups:   family [3]
  family name    role    couple
  <chr>  <chr>   <chr>   <lgl> 
1 1      John    Leader  FALSE 
2 1      Anitta  Partner TRUE  
3 1      Steven  Son     FALSE 
4 2      Stella  Leader  FALSE 
5 2      Robert  Son     FALSE 
6 3      Adam    Leader  FALSE 
7 3      William Partner TRUE  

Solution

  • With dplyr package, you can do like this:

    library(dplyr)
    
    
    families <- data.frame(family=c('1', '1', '1', '2', '2', '3', '3'),
                           name=c('John', 'Anitta', 'Steven', 'Stella', 'Robert', 'Adam', 'William'),
                           role=c('Leader', 'Partner', 'Son', 'Leader', 'Son', 'Leader', 'Partner'))
    
    families
    #>   family    name    role
    #> 1      1    John  Leader
    #> 2      1  Anitta Partner
    #> 3      1  Steven     Son
    #> 4      2  Stella  Leader
    #> 5      2  Robert     Son
    #> 6      3    Adam  Leader
    #> 7      3 William Partner
    
    families |> 
            group_by(family) |> 
            mutate(couple = any(role == "Partner"))
    #> # A tibble: 7 × 4
    #> # Groups:   family [3]
    #>   family name    role    couple
    #>   <chr>  <chr>   <chr>   <lgl> 
    #> 1 1      John    Leader  TRUE  
    #> 2 1      Anitta  Partner TRUE  
    #> 3 1      Steven  Son     TRUE  
    #> 4 2      Stella  Leader  FALSE 
    #> 5 2      Robert  Son     FALSE 
    #> 6 3      Adam    Leader  TRUE  
    #> 7 3      William Partner TRUE
    

    Created on 2024-04-25 with reprex v2.1.0