Reputation: 4970
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
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
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
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
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