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, please don't use stack
seems to be more efficient indeed.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
What Are the "Standard Unambiguous Date" Formats For String-To-Date Conversion in R
Consistent Width For Geom_Bar in the Event of Missing Data
Filter Data Frame by Character Column Name (In Dplyr)
How to Remove Outliers from a Dataset
Pass Column Name in Data.Table Using Variable
How to Get a Vertical Geom_Vline to an X-Axis of Class Date
How to Subtract Months from a Date in R
Subset Data to Contain Only Columns Whose Names Match a Condition
How to Sum a Numeric List Elements
Plotting Contours on an Irregular Grid
Ggplot, Facet, Piechart: Placing Text in the Middle of Pie Chart Slices
Labeling Outliers of Boxplots in R
How to Put Labels Over Geom_Bar For Each Bar in R With Ggplot2
Control Ggplot2 Legend Look Without Affecting the Plot
Aggregate a Dataframe on a Given Column and Display Another Column
What's Wrong With My Function to Load Multiple .Csv Files into Single Dataframe in R Using Rbind