2

I am trying to convert the following list to a dataframe.

I have tried melt/cast, ldply, unlist etc but can't seem to get the expected output.

Many thanks in advance!

df <- list( name=rep(c(11,12), each=1), value=rnorm(2), name=rep(c(13,14), each=1), value=rnorm(2) ) df 

I want the following output in a dataframe:

name value 11 1.187 12 0.691 13 0.452 14 0.898 
0

4 Answers 4

3

An option is to stack into a two column data.frame, and spread it back to 'wide' format

library(tidyverse) enframe(df) %>% unnest(value) %>% group_by(name) %>% mutate(rn = row_number()) %>% spread(name, value) %>% select(-rn) # A tibble: 4 x 2 # name value # <dbl> <dbl> #1 11 -0.484 #2 12 -0.110 #3 13 -0.328 #4 14 0.0737 

Or another option is to make use of pivot_longer from the devel version of tidyr

df %>% set_names(str_c(names(.), "_", cumsum(names(.) == "name"))) %>% as_tibble %>% mutate(rn = row_number()) %>% pivot_longer(-rn, names_to =c(".value", "group"), names_sep = '_') %>% select(name, value) 

Or using base R

reshape(transform(stack(df), rn = ave(seq_along(ind), ind, FUN = seq_along)), idvar = 'rn', direction = 'wide', timevar = 'ind') 
Sign up to request clarification or add additional context in comments.

3 Comments

I got an error for the 1st option: "row_number() should only be called in a data context". But the 2nd one worked, thank you!
@AM_123. Could be a different version of package?
It worked after I updated the package, thanks again!
2

Here's a way in base R using split -

data.frame( split(v <- unlist(df), sub("[0-9]+", "", names(v))) ) name value 1 11 -0.2282623 2 12 -0.8101849 3 13 -0.9311898 4 14 0.3638835 

Data -

df <- structure(list(name = c(11, 12), value = c(-0.22826229127103, -0.810184913338659), name = c(13, 14), value = c(-0.931189778412408, 0.363883463286674)), .Names = c("name", "value", "name", "value" )) 

Comments

2
d <- data.frame( name = unlist(df[names(df) == "name"]), value = unlist(df[names(df) == "value"]) ) 

Comments

0
the_list <- list( name=rep(c(11,12), each=1), value=rnorm(2), name=rep(c(13,14), each=1), value=rnorm(2) ) df <- data.frame(name = unlist(the_list[which(names(the_list) == "name")]), value = unlist(the_list[which(names(the_list) == "value")])) df # name value # 1 11 -0.83130395 # 2 12 -0.12782566 # 3 13 2.59769395 # 4 14 -0.06967617 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.