Named List To/From Data.Frame

Named List To/From Data.Frame

Use stack and unstack in base R:

x <- data.frame(a=1:3, b=4:6)

x
a b
1 1 4
2 2 5
3 3 6

Use stack to from wide to tall, i.e. stack the vectors on top of one another.

y <- stack(x)
y
values ind
1 1 a
2 2 a
3 3 a
4 4 b
5 5 b
6 6 b

Use unstack to do the reverse.

unstack(y)
a b
1 1 4
2 2 5
3 3 6

If your data structure is more complicated than you described, stack and unstack may no longer be suitable. In that case you'll have to use reshape in base R, or melt and dcast in package reshape2.

r data.frame to a named list

One option is to deframe to create a named vector and then use as.list. to convert each element as a list element

library(tibble)
library(dplyr)
deframe(d) %>%
as.list

Or in base R with split

with(d, split(value, key))

convert named list with mixed content to data frame

We can use stack from base R

stack(my_list)

According to ?stack

The stack function is used to transform data available as separate columns in a data frame or list into a single column that can be used in an analysis of variance model or other linear model. The unstack function reverses this operation.


Or with enframe

library(tidyverse)
enframe(my_list) %>% # creates the 'value' as a `list` column
mutate(value = map(value, as.character)) %>% # change to single type
unnest

Named list to data frame

I'd use the melt function in reshape2:

> reshape2::melt(namedList)
value L1
1 a A
2 b A
3 c A
4 d A
5 g A
6 a B
7 c B
8 d B
9 e B
>

Or stack:

> stack(namedList)
values ind
1 a A
2 b A
3 c A
4 d A
5 g A
6 a B
7 c B
8 d B
9 e B
>

Turn a dataframe into a named list of dataframes with names from a column in R

We can use:

library(tibble)
as.list(deframe(df))

Two Column R Dataframe to Named LIst

You could use unstack:

as.list(unstack(rev(df)))

$driver.R
[1] "A" "F" "G"

$fooBar.R
[1] "A" "B" "C"

This is equivalent to as.list(unstack(df, keyWord~file))

Convert named list to a data.frame efficiently

Try stack

stack(ob)
# values ind
#1 2 a
#2 3 b

You would need to change the names though. Use setNames

setNames(stack(ob), nm = c("value", "key"))

benchmark

Addressing @Roland's comment, stack seems to be more efficient indeed. please don't use stack but OP's solution for efficiency reasons.

n <- 1e5
lst <- as.list(seq_len(n))
names(lst) <- paste0("a", seq_len(n))

library(microbenchmark)
benchmark <- microbenchmark(
snoram = snoram(lst),
markus = markus(lst), times = 50
)
benchmark
#Unit: milliseconds
# expr min lq mean median uq max neval
# snoram 2.475258 2.594479 2.739639 2.652843 2.715575 5.92216 50
# markus 114.387692 119.028200 134.745626 137.524606 144.045112 162.11510 50

Functions used (so far)

snoram <- function(l) {
data.frame(key = names(l), value = unlist(l, use.names = FALSE),
stringsAsFactors = FALSE) # this gives a hugh performance gain
# thanks to @Roland
}

markus <- function(l) {
setNames(stack(l), nm = c("value", "key"))
}

Turning a dataframe into named list

setNames(as.list(as.character(colors$id)), nm = colors$color)
$Gold
[1] "1"

$Green
[1] "2"

$Red
[1] "3"

How to change a dataframe in R to a named list?

Here's a way to slice the data.frame, melt the dataset to a long format and return only the exams taken.

library(tidyr)

xy <- data.frame(student_id = 1:4, math_exam = c(0, 1, 0, 1), spanish_exam = c(1, 0, 0, 1))

xy <- split(xy, xy$student_id)

result <- lapply(xy, FUN = function(x) {
out <- gather(x, key = exam, value = taken, -student_id)
out[out$taken == 1, ][, -3]
})

do.call(rbind, result)

student_id exam
1 1 spanish_exam
2 2 math_exam
4.1 4 math_exam
4.2 4 spanish_exam

If you fancy a dplyr solution...

library(dplyr)

xy %>%
group_by(student_id) %>%
gather(key = exam, value = taken, -student_id) %>%
filter(taken == 1) %>%
select(-taken)

Source: local data frame [4 x 2]
Groups: student_id [3]

student_id exam
<int> <chr>
1 2 math_exam
2 4 math_exam
3 1 spanish_exam
4 4 spanish_exam


Related Topics



Leave a reply



Submit