tidyr::unnest() with different column types
Asked Answered
C

2

5

Since the update to tidyr version 1.0.0 I have started to get an error when unnesting a list of dataframes.

The error comes because some of the data frames in the list contain a column with all NA values (logical), while other of the dataframes contain the same column but with some character values (character). The columns with all NA values are coded as logicals while the others are coded as character vectors.

The default behavior of earlier versions of tidyr handled the different column types without problems (at least I didn't get this error when running the script).

Can I solve this issue from inside tidyr::unest() ?

Reproducible example:

library(tidyr)

a <- tibble(
  value = rnorm(3),
  char_vec = c(NA, "A", NA))

b <- tibble(
  value = rnorm(2),
  char_vec = c(NA, "B"))

c <- tibble(
  value = rnorm(3),
  char_vec = c(NA, NA, NA))

tibble(
  file = list(a, b, c)) %>% 
  unnest(cols = c(file))
#> No common type for `..1$file$char_vec` <character> and `..3$file$char_vec`
#> <logical>.

Created on 2019-10-11 by the reprex package (v0.3.0)

Corticosterone answered 11/10, 2019 at 8:36 Comment(4)
you can still use the older unnest with tibble(file = list(a, b, c)) %>% unnest_legacy(file) Raymundorayna
Or put this in between mutate(file = map(file, ~ mutate(.x, char_vec = as.character(char_vec))))Africanize
unnest <- unnest_legacy before tibble ...Waft
Thanks for the comments, they are all helpful. @Africanize - Can you submit an answer? I think your solution is the best long-term solution. Cheers.Corticosterone
A
4

You can convert all relevant columns to character one step before unnesting.

tibble(
  file = list(a, b, c)) %>% 
  mutate(file = map(file, ~ mutate(.x, char_vec = as.character(char_vec)))) %>%
  unnest(cols = c(file))

If there are several columns that need treatment you can do:

 tibble(
  file = list(a, b, c)) %>% 
  mutate(file = map(file, ~ mutate_at(.x, vars(starts_with("char")), ~as.character(.)))) 

Data for the latter example:

a <- tibble(
  value = rnorm(3),
  char_vec = c(NA, "A", NA),
  char_vec2 = c(NA, NA, NA))

b <- tibble(
  value = rnorm(2),
  char_vec = c(NA, "B"),
  char_vec2 = c("C", "A"))

c <- tibble(
  value = rnorm(3),
  char_vec = c(NA, NA, NA),
  char_vec2 = c("B", NA, "A"))

Africanize answered 11/10, 2019 at 17:58 Comment(0)
T
0

Had a similar issue and came across this thread. The accepted answer doesn`t work any more with purrr > 1.0.0, I believe.

In case of your problem, you can just use rbind:

rbind(a, b, c)
Tomlin answered 3/10, 2023 at 8:15 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.