How to keep other values unchanged with dplyr's recode_factor

Viewed 119

In the example below, recoding some values makes all the other NA. How can I keep the other values unchanged?

library(tibble)
library(dplyr)

test <- tibble(
  test_vec = as.factor(c(1, 2, 3))
)
test
#> # A tibble: 3 x 1
#>   test_vec
#>   <fct>   
#> 1 1       
#> 2 2       
#> 3 3

test %>% 
  mutate(test_vec = recode_factor(test_vec, `3` = 4))
#> # A tibble: 3 x 1
#>   test_vec
#>   <fct>   
#> 1 <NA>    
#> 2 <NA>    
#> 3 4
4 Answers

Need to make your replacement the same type as the original value.

test %>% 
  mutate(test_vec = recode_factor(test_vec, "3" = "4"))

# A tibble: 3 x 1
  test_vec
  <fct>   
1 1       
2 2       
3 4   

Using fct_recode

library(forcats)
library(dplyr)
test %>%
    mutate(test_vec = fct_recode(test_vec, `4` = '3'))

-output

# A tibble: 3 x 1
#  test_vec
#  <fct>   
#1 1       
#2 2       
#3 4    

So that you don't get missing NA values, you have to list the other values in the function as well.

test %>% 
   mutate(test_vec = recode_factor(test_vec, `1` = 1, `2` = 2, `3` = 4))

Result

# A tibble: 3 x 1
  test_vec
  <fct>   
1 1       
2 2       
3 4

Another way to do it is using case_when, but for this you have to start from numerical values. I give you an example starting from numerical values and I convert them to factor.

test <- tibble(
   test_vec = (c(1, 2, 3)))
test %>% 
   mutate(test_vec = case_when( test_vec != 3 ~ test_vec,
                                test_vec == 3 ~ 4)) %>% 
   mutate(across(test_vec,factor))

Result

# A tibble: 3 x 1
  test_vec
  <fct>   
1 1       
2 2       
3 4  
Related