Home > OS >  How to do a for loop with case_when
How to do a for loop with case_when

Time:10-13

I'm a beginner with R and I'm trying to do a for-loop to recode many variables: when "test" modality is missing, then have "test.v1" modality. It looked very easy to do, but I can't get it:

VEC_1 <- c("test1","test2","test3","test4","test5","test6","test7","test8","test9")
VEC_2 <- c("test1.v1","test2.v1","test3.v1","test4.v1","test5.v1","test6.v1","test7.v1","test8.v1","test9.v1") 
 
for (i in 1:(min(length(VEC_1), length(VEC_2)))){
    df2 <- df1 %>%
        mutate(
          VEC_1[i] = case_when(
          is.na(VEC_1[i]) & !is.na(VEC_2[i]) ~ VEC_2[i],
          TRUE ~ VEC_1[i])
    )
}

I have this error

Unexpected error : '=' in:
"    mutate(
      VEC_1[i] ="

Does anyone have an idea ?

CodePudding user response:

I'm assuming VEC_1 and VEC_2 are the same length here. you don't need to use a for-loop, mutate affects the whole column of the dataframe, it kinda behaves like a for-loop. I have rewritten your code like this and changed the data for testing purposes:

library(dplyr)

VEC_1 <- c("test1","test2","test3","test4",NA,"test6","test7",NA,"test9")
VEC_2 <- c("test1.v1",NA,"test3.v1","test4.v1","test5.v1","test6.v1","test7.v1",NA,"test9.v1") 

df <- data.frame(VEC_1,VEC_2)

df %>% mutate(VEC_1 = if_else(is.na(VEC_1) & !is.na(VEC_2),VEC_2,VEC_1))

which is equal to

df <- data.frame(VEC_1,VEC_2)

for (i in 1:nrow(df)){
  if(is.na(df$VEC_1[i]) & !is.na(df$VEC_2[i])){
    df$VEC_1[i] = df$VEC_2[i]
  }
}

Output:

> df
     VEC_1    VEC_2
1    test1 test1.v1
2    test2     <NA>
3    test3 test3.v1
4    test4 test4.v1
5 test5.v1 test5.v1
6    test6 test6.v1
7    test7 test7.v1
8     <NA>     <NA>
9    test9 test9.v1

i also changed from case_when to if_else, because you only check one condition.

?if_else
if_else(condition, true, false, missing = NULL)

CodePudding user response:

ifelse/if_else will be a good solution, unless you have multiple conditions, then case_when is your friend. A loop isn't necessary:

library(dplyr)

VEC_1 <- c("test1","test2",NA,NA)
VEC_2 <- c("test1.v1",NA,NA,"test4.v1") 

df <- tibble(VEC_1, VEC_2)    

df %>% 
  mutate(VEC_1 = case_when(
    is.na(VEC_2) ~ VEC_1,
    is.na(VEC_1) ~ VEC_2, 
    TRUE ~ VEC_1)
  )

# A tibble: 4 × 2
  VEC_1 VEC_2   
  <chr> <chr>   
1 test1 test1.v1
2 test2 NA      
3 NA    NA      
4 NA    test4.v1

# A tibble: 4 × 2
  VEC_1    VEC_2   
  <chr>    <chr>   
1 test1    test1.v1
2 test2    NA      
3 NA       NA      
4 test4.v1 test4.v1
  • Related