AM_123
AM_123

Reputation: 215

Convert List to a Dataframe

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

Upvotes: 2

Views: 99

Answers (4)

akrun
akrun

Reputation: 887118

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')

Upvotes: 3

Gregory
Gregory

Reputation: 4279

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

Upvotes: 0

Christopher Cooper
Christopher Cooper

Reputation: 71

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

Upvotes: 2

Shree
Shree

Reputation: 11140

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"
))

Upvotes: 2

Related Questions