Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert R list to dataframe with missing/NULL elements

Given a list:

alist = list(
  list(name="Foo",age=22),
  list(name="Bar"),
  list(name="Baz",age=NULL)
 )

what's the best way to convert this into a dataframe with name and age columns, with missing values (I'll accept NA or "" in that order of preference)?

Simple methods using ldply fail because it tries to convert each list element into a data frame, but the one with the NULL barfs because the lengths don't match. Best I have at the moment is:

> ldply(alist,function(s){t(data.frame(unlist(s)))})
  name  age
1  Foo   22
2  Bar <NA>
3  Baz <NA>

but that's pretty icky and the numeric variable becomes a factor...

like image 978
Spacedman Avatar asked Apr 03 '13 17:04

Spacedman


People also ask

How do I remove missing values from a list in R?

Firstly, we use brackets with complete. cases() function to exclude missing values in R. Secondly, we omit missing values with na. omit() function.

How do I convert a list to a DataFrame in R studio?

Convert List to DataFrame using data. data. frame() is used to create a DataFrame in R that takes a list, vector, array, etc as arguments, Hence, we can pass a created list to the data. frame() function to convert list to DataFrame. It will store the elements in a single row in the DataFrame.

How do you find missing values in R programming?

In R, missing values are represented by the symbol NA (not available). Impossible values (e.g., dividing by zero) are represented by the symbol NaN (not a number). Unlike SAS, R uses the same symbol for character and numeric data.

Is null in R DataFrame?

The R function is. null indicates whether a data object is of the data type NULL (i.e. a missing value). The function returns TRUE in case of a NULL object and FALSE in case that the data object is not NULL.


2 Answers

Step1: remove NULL items

non.null.list <- lapply(alist, Filter, f = Negate(is.null))

Step2: stack everything together:

library(plyr)
rbind.fill(lapply(non.null.list, as.data.frame))
#   name age
# 1  Foo  22
# 2  Bar  NA
# 3  Baz  NA

Edit: In case you had a variable that is NULL for all your list items, it would not show up in your final output. If instead, you'd like a column filled with NA, the first step should not remove NULLs but replace them with NAs:

Step 1 alternative: replace NULL with NA:

non.null.list <- lapply(alist, lapply, function(x)ifelse(is.null(x), NA, x))
like image 172
flodel Avatar answered Oct 04 '22 11:10

flodel


A comment mentioned wanting only a single loop, which can be achieved with @flodel's answer just by putting the body of the two loops together:

rbind.fill(lapply(alist, function(f) {
  as.data.frame(Filter(Negate(is.null), f))
}))

giving

  name age
1  Foo  22
2  Bar  NA
3  Baz  NA
like image 42
Brian Diggs Avatar answered Oct 04 '22 10:10

Brian Diggs