Gentlemiao
Gentlemiao

Reputation: 33

Convert list to a two column data frame in R

I have a list looks like this:

$ key_1
[1] "value_1" "value_2" "value_3"

$ key_2
[1] "value_1" "value_4" "value_5"

$ key_3
[1] "value_2" "value_5" "value_6"

...
...
lots of data

How to convert it to a two column data frame looks like this:

head(df)

    Key     Value
1   key_1   value_1, value_2, value_3
2   key_2   value_1, value_4, value_5
3   key_3   value_2, value_5, value_6
....
....

Thanks in advance

Upvotes: 3

Views: 945

Answers (4)

stallingOne
stallingOne

Reputation: 4006

I found this one to be shorter and easier to read as well:

data.frame(stack(lst))

which I use like this to have nicer names:

df = data.frame(stack(lst)) %>% rename(Key = ind, Value = values)

Upvotes: 0

abalter
abalter

Reputation: 10393

Turns out tibble has a method for that called enframe.

library(tidyverse)

l = map(1:3, ~str_glue("value_{.}{1:3}")) %>% set_names(str_glue("key_{1:3}"))
print(l)
#> $key_1
#> value_11
#> value_12
#> value_13
#> 
#> $key_2
#> value_21
#> value_22
#> value_23
#> 
#> $key_3
#> value_31
#> value_32
#> value_33

df = enframe(l)
print(df)
#> # A tibble: 3 × 2
#>   name  value     
#>   <chr> <list>    
#> 1 key_1 <glue [3]>
#> 2 key_2 <glue [3]>
#> 3 key_3 <glue [3]>
df %>% unnest(value) %>% print()
#> # A tibble: 9 × 2
#>   name  value   
#>   <chr> <glue>  
#> 1 key_1 value_11
#> 2 key_1 value_12
#> 3 key_1 value_13
#> 4 key_2 value_21
#> 5 key_2 value_22
#> 6 key_2 value_23
#> 7 key_3 value_31
#> 8 key_3 value_32
#> 9 key_3 value_33
df %>% pull(value) %>% print()
#> [[1]]
#> value_11
#> value_12
#> value_13
#> 
#> [[2]]
#> value_21
#> value_22
#> value_23
#> 
#> [[3]]
#> value_31
#> value_32
#> value_33

deframe(df) %>% print()
#> $key_1
#> value_11
#> value_12
#> value_13
#> 
#> $key_2
#> value_21
#> value_22
#> value_23
#> 
#> $key_3
#> value_31
#> value_32
#> value_33

Created on 2023-10-05 with reprex v2.0.2

Upvotes: 0

J. Ring
J. Ring

Reputation: 333

temp_list <- list(key_1 = c('value_1', 'value_2', 'value_3'),
              key_2 = c('value_1', 'value_4', 'value_5'),
              key_3 = c('value_2', 'value_5', 'value_6'))
data.frame(Key = names(temp_list), Value = do.call(paste, c(temp_list, list(sep = ', '))))

You can do it this way with base R

Upvotes: 2

Ronak Shah
Ronak Shah

Reputation: 389175

You can use stack to get a named list to dataframe and then use aggregate :

aggregate(values~ind, stack(lst), toString)

Using tidyverse functions.

tibble::enframe(lst) %>%
  dplyr::mutate(value = purrr::map_chr(value, toString))

#  name  value                    
#  <chr> <chr>                    
#1 key1  value_1, value_2, value_3
#2 key2  value_1, value_4, value_5
#3 key3  value_2, value_5, value_6

data

lst <- list(key1 = c("value_1", "value_2" ,"value_3"), 
            key2 = c("value_1", "value_4", "value_5"), 
            key3 = c("value_2", "value_5", "value_6"))

Upvotes: 2

Related Questions