Creating new column by group using mutate and case_when based on one existing column

Dear Members of the community,

First, I have to confess that I am new to R.

Quite similar to this Create new column based on condition from other column per group using tidy evaluation [Solved], I want to create a new column that evaluate "contract" to create a new variable "eval".
My dataset is structured as follow: 1 person (here 1,2 or 3 in "group") can have one or more contracts (here A and/or B in "contract").

df <- data.frame(group = c(1,1,1,2,2,2,3,3,3), 
                 contract  = c("A","A","A","A","B","A","B","B","B"))

I need to create a new column to evaluate the contract of the person: underinsured if she has only contract A, insured if she has contract A and B and overinsured if she hase only contract B:

df <- df %>%
  group_by(group) %>%
  mutate(eval =  case_when((contract == "A" && contract != "B") ~ "under insured", 
                           (contract == "A" && contract == "B") ~ "insured", 
                           (contract != "A" && contract == "B") ~ "over insured"))

Of course this code doesn't work. I obtain this dataframe:

# A tibble: 9 x 3
# Groups:   group [3]
  group contract eval         
  <dbl> <chr>    <chr>        
1     1 A        under insured
2     1 A        under insured
3     1 A        under insured
4     2 A        under insured
5     2 B        under insured
6     2 A        under insured
7     3 B        over insured 
8     3 B        over insured 
9     3 B        over insured 

But the result I want is as follow:

  group contract          eval
1     1        A under insured
2     1        A under insured
3     1        A under insured
4     2        A       insured
5     2        B       insured
6     2        A       insured
7     3        B  over insured
8     3        B  over insured
9     3        B  over insured

As I mentioned, I am new to R /RStudio and any help would be greatly appreciated!

Thanks!

Use %in% operator to check whether an element is part of a set or not.

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union

df <- data.frame(group = c(1,1,1,2,2,2,3,3,3), 
                 contract  = c("A","A","A","A","B","A","B","B","B"))

df %>%
    group_by(group) %>%
    mutate(eval = case_when((("A" %in% contract) && !("B" %in% contract)) ~ "under insured", 
                            (("A" %in% contract) && ("B" %in% contract)) ~ "insured", 
                            (!("A" %in% contract) && ("B" %in% contract)) ~ "over insured")) %>%
    ungroup()
#> # A tibble: 9 x 3
#>   group contract eval         
#>   <dbl> <chr>    <chr>        
#> 1     1 A        under insured
#> 2     1 A        under insured
#> 3     1 A        under insured
#> 4     2 A        insured      
#> 5     2 B        insured      
#> 6     2 A        insured      
#> 7     3 B        over insured 
#> 8     3 B        over insured 
#> 9     3 B        over insured

Created on 2021-03-18 by the reprex package (v1.0.0)

Hope this helps.

Dear Yarnabrina,

It works perfectly! Many thanks for the help!

Best regards,

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.