Home > database >  How to keep zero-length element when using c() on a list?
How to keep zero-length element when using c() on a list?

Time:06-08

Context: I have a list of Dates objects as an ouput from a function. Some of them can be Date of length 0.

Problem: When I concatenate the elements of the list to get a vector (i.e. do.call(c, mylist)), the latters are dropped. This cause problems when I try to add this vector as a column in a pre-existing dataframe.

Question: Is it possible to "keep" these Date of length 0 elements into the final vector? Do you know a better way to acheive the expected result?

ex_list <- list(structure(14467, class = "Date"), 
                structure(14567, class = "Date"),
                structure(numeric(0), class = "Date"))
ex_list
#> [[1]]
#> [1] "2009-08-11"
#> 
#> [[2]]
#> [1] "2009-11-19"
#> 
#> [[3]]
#> Date of length 0
ex_vector <- do.call(c, ex_list)
ex_vector # the Date of length 0 is dropped
#> [1] "2009-08-11" "2009-11-19"
df <- data.frame(id = c("A", "B", "C"))
df$dates <- ex_vector
#> Error in `$<-.data.frame`(`*tmp*`, dates, value = structure(c(14467, 14567: le tableau de remplacement a 2 lignes, le tableau remplacé en a 3

Created on 2022-06-07 by the reprex package (v2.0.1)

Expected output:

id dates
A 2009-08-11
B 2009-11-19
C NA

CodePudding user response:

For use in a data frame you'd prefer NA's over Date(0). E.g.

ex_list[sapply(ex_list, rlang::is_empty)] <- NA
ex_vector <- do.call(c, ex_list)
df <- data.frame(id = c("A", "B", "C"))
df$dates <- ex_vector

Or a tidyverse-solution:

library(tidyverse)

data.frame(id = c("A", "B", "C")) |>
  add_column(as_tibble_col(ex_list, column_name = "dates")) |>
  unnest(dates, keep_empty = TRUE)
  •  Tags:  
  • r
  • Related