missing factors when `unlist()` or `flatten()` a list

Viewed 104

When unlisting unlist() or flattening flatten() a list with a factor variable, factors values are lost in the process. Additionally, when unlist() everything is converted into "character". Which is the correct way to proceed? Below is my desired output. Thanks.

L <- list(x = structure(1L, .Label = c("Jujutsu", "Kaisen"), class = "factor"), 
          y = 2020,
          z = "Shinjuku")

unlist()

unlist(L)
# x          y          z 
# "1"     "2020" "Shinjuku" 

flatten()

flatten(L)
# $x
# [1] 1
# 
# $y
# [1] 2020
# 
# $z
# [1] "Shinjuku"

Desired output.

# $x
# [1] "Jujutsu" 
# 
# $y
# [1] 2020
# 
# $z
# [1] "Shinjuku"
3 Answers

You can check for is.factor and convert the subset.

f <- sapply(L, is.factor)
L[f] <- lapply(L[f], as.character)
L
# $x
# [1] "Jujutsu"
# 
# $y
# [1] 2020
# 
# $z
# [1] "Shinjuku"

This also gives you the vector.

unlist(L)
#         x          y          z 
# "Jujutsu"     "2020" "Shinjuku" 

The "2020" will stay character though, because all elements of a vector have to be the same type.

Try type.convert if you are with base R

> type.convert(L, as.is = TRUE)
$x
[1] "Jujutsu"

$y
[1] 2020

$z
[1] "Shinjuku"

One option could be:

map(.x = L, ~ if(is.factor(.x)) as.character(.x) else .x)

$x
[1] "Jujutsu"

$y
[1] 2020

$z
[1] "Shinjuku"
Related