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