R applying if_else and sum to each element in a dataframe

Viewed 34

I need to generate column zip3 out of zip1 and zip2. zip2 is the first 5 characters of zip1.

To generate zip3 if zip2 did NOT exist in the entire zip1 column then zip1 value will be chosen otherwise zip2 will be chosen.

How can I do this easily without a loop? I tried this, but I cannot apply it to the entire DF

df <- structure(list(zip1 = c("12345-1234", "12345", "55555", "11111", 
"22222-1234", "55555-1234", "11111", "66666-1234"), zip2 = c(12345L, 
12345L, 55555L, 11111L, 22222L, 55555L, 11111L, 66666L), zip3 = c("12345", 
"12345", "55555", "11111", "22222-1234", "55555", "11111", "66666-1234"
)), class = "data.frame", row.names = c(NA, -8L))

library(dplyr)
df <- df %>% mutate(zip3=if_else(sum(df$zip1==zip2)>0,zip2,zip1))

enter image description here

2 Answers

You can use case_when from dplyr package. First zip2 should be character

library(dplyr)
df$zip2 <- as.character(df$zip2)
df <- df %>% 
  mutate(zip3 = case_when(zip2 %in% zip1 ~ zip2,
                          TRUE ~ zip1))

Output:

        zip1  zip2       zip3
1 12345-1234 12345      12345
2      12345 12345      12345
3      55555 55555      55555
4      11111 11111      11111
5 22222-1234 22222 22222-1234
6 55555-1234 55555      55555
7      11111 11111      11111
8 66666-1234 66666 66666-1234

We can do a rowwise and then with if/else return the 'zip2' or 'zip1' based on the condition

library(dplyr)    
df %>%
    rowwise %>% 
    mutate(zip3 = if(zip2 %in% df$zip1) as.character(zip2) else zip1) %>%
    ungroup

-output

# A tibble: 8 x 3
  zip1        zip2 zip3      
  <chr>      <int> <chr>     
1 12345-1234 12345 12345     
2 12345      12345 12345     
3 55555      55555 55555     
4 11111      11111 11111     
5 22222-1234 22222 22222-1234
6 55555-1234 55555 55555     
7 11111      11111 11111     
8 66666-1234 66666 66666-1234
Related