Simon
Simon

Reputation: 685

Working with lists in R: say no to for loops?

I would like to find a better way to collapse a list into a dataframe based on a logical function in R. Here's a reproducible example of what worked for me:

a <- data.frame(foo = c(1:3), bar = c(letters[1:3]))
bazL <- list(c("a", "z", "g"), NULL, "c")

a$baz <- NULL
for(i in 1:length(a$foo)) {
  a$baz[i] <- (bazL[[i]] > 0)[1]
}

In my use case, each list item corresponded to a dataframe row. I wanted to know whether the corresponding list item was empty or not. I'm sure there's a better way than the approach above.

How would you do it?

Upvotes: 1

Views: 53

Answers (3)

beigel
beigel

Reputation: 1200

You can use the map function provided by the purrr package. For example,

library(dplyr)
library(purrr)

a <- mutate(a, baz = map(bazL, ~ !is.null(.x)))

Here map takes in bazL as the list it iterates over (be careful though, if the dataframe a has a column named bazL, mutate will think you are referring to that bazL, not the globally defined one), and applies the is.null function to each element of bazL, then negates with !. The .x is just a placeholder here for each element of bazL and we use the formula interface.

Upvotes: 1

akrun
akrun

Reputation: 886938

We can use Filter to filter out the NULL elements in list

Filter(Negate(is.null), bazL)

Or for getting a logical vector

lengths(bazL)>0
#[1]  TRUE FALSE  TRUE

Upvotes: 2

d.b
d.b

Reputation: 32538

You could use the is.null to check if each list item is empty or not

#a$baz = 
!sapply(bazL, is.null)
#[1]  TRUE FALSE  TRUE

Upvotes: 3

Related Questions