milan
milan

Reputation: 4970

Convert list to dataframe in R and add column with names of sub-lists

List l has three strings that are named one, two, and three, respectively. I want to convert l to a dataframe, and I need an additional column with the names in n.

l <- list(c("a", "b"), c("c", "d", "e"), c("e"))
n <- c("one", "two", "three")

I can do it using a loop, but I'm sure there are more efficient ways of doing this.

out <- NULL
for (i in 1:length(n)){
  step <- rep(n[i], length(l[[i]]))
  out <- c(out, step)}

df <- as.data.frame(unlist(l))
df$n <- out
df

#  unlist(l)     n
#1         a   one
#2         b   one
#3         c   two
#4         d   two
#5         e   two
#6         e three

Upvotes: 7

Views: 5852

Answers (4)

akrun
akrun

Reputation: 887153

Another option is melt from reshape2

library(reshape2)
melt(setNames(l, n))
#  value    L1
#1     a   one
#2     b   one
#3     c   two
#4     d   two
#5     e   two
#6     e three

Or with base R

data.frame(value = unlist(l), key = rep(n, lengths(l)))
#   value   key
#1     a   one
#2     b   one
#3     c   two
#4     d   two
#5     e   two
#6     e three

Upvotes: 1

akuiper
akuiper

Reputation: 214957

Another option is to use stack after setting the name for each element of the list to be the vector:

stack(setNames(l, n))

#  values   ind
#1      a   one
#2      b   one
#3      c   two
#4      d   two
#5      e   two
#6      e three

Upvotes: 4

Gregor Thomas
Gregor Thomas

Reputation: 145785

Another similar base R option:

do.call(rbind, Map(f = expand.grid, l = l, n = n, stringsAsFactors = F))
#   l     n
# 1 a   one
# 2 b   one
# 3 c   two
# 4 d   two
# 5 e   two
# 6 e three

Upvotes: 3

user1357015
user1357015

Reputation: 11686

Using base R, you can essentially do it in two lines.

l <- list(c("a", "b"), c("c", "d", "e"), c("e"))
n <- c("one", "two", "three")

#Create an appropriately sized vector of names
nameVector <- unlist(mapply(function(x,y){ rep(y, length(x)) }, l, n))

#Create the result
resultDF <- cbind.data.frame(unlist(l), nameVector)


> resultDF
  unlist(l) nameVector
1         a        one
2         b        one
3         c        two
4         d        two
5         e        two
6         e      three

Upvotes: 5

Related Questions