How to unlist a data frame column that is a list

Viewed 99

Suppose I have this data frame:

df <- data.frame(a=c(1,2))
df$b <- list(NULL, NULL)

Note that sum(is.null(df$b) is 0 because b is a list, not a vector.

How do I get it to be a vector? Some things I tried that didn't work:

# does nothing
df <- df %>% flatten(b)
# removes column b!
df <- df %>% mutate(b=unlist(b))
# destroys df
df <- df %>% unnest(cols=c(b))
# doesn't run
df <- df %>% mutate_at(vars=c('b'), funs(unlist))

There are already several questions that ask this, but their solutions did not work for me.

I am trying to get through data from jsonlite, similar data to this question.

3 Answers

Set up data:

df <- data.frame(a=c(1,2,3))
df$b <- list(NULL, NULL, 4)

Unlist:

df$d <- unlist(lapply(df$b, function(x) ifelse(is.null(x), NA, x)))

Verify the answer:

df
#   a    b  d
# 1 1 NULL NA
# 2 2 NULL NA
# 3 3    4  4

str(df)
'data.frame':   3 obs. of  3 variables:
 $ a: num  1 2 3
 $ b:List of 3
  ..$ : NULL
  ..$ : NULL
  ..$ : num 4
 $ d: num  NA NA 4

We can use map to replace the NULL elements with NA and then unnest

library(dplyr)
library(tidyr)
library(purrr)
df %>%
    mutate(b = map(b, ~ replace(., is.null(.), NA))) %>% 
    unnest(c(b))
# A tibble: 2 x 2
#      a b    
#  <dbl> <lgl>
#1     1 NA   
#2     2 NA   

Or a hacky option is

df %>%
    mutate(b = coalesce(NA, unlist(b)))
#  a  b
#1 1 NA
#2 2 NA

When there are only NULL elements, it needs to be converted to other value e.g. NA or else it would not work in a vector

c(NULL, NULL)
#NULL

Starting with the data frame of @Sathish:

df <- data.frame(a=c(1,2,3))
df$b <- list(NULL, NULL, 4)

code to transform:

is.na(df$b) <- lengths(df$b)==0
df$b <- unlist(df$b)

df
  a  b
1 1 NA
2 2 NA
3 3  4
Related