Storing a List Within a Data Frame Element in R

Storing a list within a data frame element in R

The option mentioned in my comment, i.e. simply using a list for one of the columns:

dat <- data.frame(Start = 3:4, End = c(6,10))
> dat
Start End
1 3 6
2 4 10
> dat$Elements <- list(4:5,7:9)
> dat
Start End Elements
1 3 6 4, 5
2 4 10 7, 8, 9

You could also of course ditch data frames entirely and simply use a plain old list (which might make more sense in a lot of cases, anyway):

list(list(Start = 3,End = 6, Elements = 4:5),list(Start = 4,End = 10,Elements = 7:9))
[[1]]
[[1]]$Start
[1] 3

[[1]]$End
[1] 6

[[1]]$Elements
[1] 4 5

[[2]]
[[2]]$Start
[1] 4

[[2]]$End
[1] 10

[[2]]$Elements
[1] 7 8 9

How can I save a list of lists as a column into a data.frame object in R

Here is one quick and dirty way of doing it

Meal <- function(name, ingredients, time_to_cook = NA, time_of_day = "Dinner", cuisine = NA) {
m <- data.frame(name = name, time = time_to_cook, meal = time_of_day, cuisine = cuisine)
m$ingredients <- list(ingredients)
m
}

burritos <- Meal("Burrito", ingredients = c("Tortilla", "Chicken Breast", "Sour Cream", "Pepper", "Onion", "Chili Paste"), time_to_cook = "Fast", cuisine = "Mexican")
pizza <- Meal("Pizza", ingredients = c("Flour", "Tinned Tomato", "Mozarella", "Garlic"))

based off of this answer

R Include lists of Strings in Dataframe

Thanks for all the suggestions everyone! I think I found a simpler solution though. Just in case anyone else has a similar problem in the future, this is what I did:

a <- c(1,2,3)
b <- c("a","b")
c <- c(1L,3L,5L,4L)
d <- c(TRUE,FALSE,TRUE)
e <- list(b,c,d);e

DF <- data.frame(a,I(e));DF

The I() inhibit function apparently prevents the lists from being converted and the column behaves just like a list of lists as far as I can tell so far. The class of the e column is however not "list" but "AsIs". I don't know whether this might cause problems further down the line, if so, I will update this answer!

EDIT

So it turns out that some functions do not take the AsIs class as input. To convert it back to a usefull character string, you can simply use unlist() on every row.

Making a nested list with a dataframe in R

Something like this ought to work:

data <- read.table(header = TRUE, text = "
ID pos strand nucleotide count
id1 12 + A 13
id1 13 + C 25
id2 24 + G 10
id2 25 + T 25
id2 26 + A 10
id3 10 + C 5
")

l <- split(unname(split(data, seq_len(nrow(data)))), data$ID)
ll <- Map(list, names(l), l)
ll
## $id1
## $id1[[1]]
## [1] "id1"
##
## $id1[[2]]
## $id1[[2]][[1]]
## ID pos strand nucleotide count
## 1 id1 12 + A 13
##
## $id1[[2]][[2]]
## ID pos strand nucleotide count
## 2 id1 13 + C 25
##
##
##
## $id2
## $id2[[1]]
## [1] "id2"
##
## $id2[[2]]
## $id2[[2]][[1]]
## ID pos strand nucleotide count
## 3 id2 24 + G 10
##
## $id2[[2]][[2]]
## ID pos strand nucleotide count
## 4 id2 25 + T 25
##
## $id2[[2]][[3]]
## ID pos strand nucleotide count
## 5 id2 26 + A 10
##
##
##
## $id3
## $id3[[1]]
## [1] "id3"
##
## $id3[[2]]
## $id3[[2]][[1]]
## ID pos strand nucleotide count
## 6 id3 10 + C 5

Here, ll is named list of 2-element lists of the form

list(<ID>, <list of 1-row data frames>)

as desired. However, it would be much more natural to use l, rather than ll, as your "dictionary", because then you could do (say) l$id1 to retrieve the list of id1 rows, rather than ll$id1[[2L]]. ll$id1[[1L]] is completely redundant, because names attribute of ll already specifies the position of each ID.

Convert a list to a data frame

Update July 2020:

The default for the parameter stringsAsFactors is now default.stringsAsFactors() which in turn yields FALSE as its default.


Assuming your list of lists is called l:

df <- data.frame(matrix(unlist(l), nrow=length(l), byrow=TRUE))

The above will convert all character columns to factors, to avoid this you can add a parameter to the data.frame() call:

df <- data.frame(matrix(unlist(l), nrow=132, byrow=TRUE),stringsAsFactors=FALSE)

How do I make a list of data frames?

This isn't related to your question, but you want to use = and not <- within the function call. If you use <-, you'll end up creating variables y1 and y2 in whatever environment you're working in:

d1 <- data.frame(y1 <- c(1, 2, 3), y2 <- c(4, 5, 6))
y1
# [1] 1 2 3
y2
# [1] 4 5 6

This won't have the seemingly desired effect of creating column names in the data frame:

d1
# y1....c.1..2..3. y2....c.4..5..6.
# 1 1 4
# 2 2 5
# 3 3 6

The = operator, on the other hand, will associate your vectors with arguments to data.frame.

As for your question, making a list of data frames is easy:

d1 <- data.frame(y1 = c(1, 2, 3), y2 = c(4, 5, 6))
d2 <- data.frame(y1 = c(3, 2, 1), y2 = c(6, 5, 4))
my.list <- list(d1, d2)

You access the data frames just like you would access any other list element:

my.list[[1]]
# y1 y2
# 1 1 4
# 2 2 5
# 3 3 6

In R iterate a function over a list of dataframes then store the output into a list with each output element named by input data frame

use tidyverse

If I understood you correctly

library(FNN)
library(tidyverse)
Kmeans.list <- map(.x = mylist,
.f = ~kmeans(scale(.x[,-c(1:2)]),
centers =15,
nstart=50,
iter.max = 100)) %>%
purrr::set_names(c("df1", "df2"))

Kmeans_centers <- map(Kmeans.list, ~.x$centers)

n500 <- map2(
.x = mylist,
.y = Kmeans_centers,
.f = ~ get.knnx(data = scale(.x[, -c(1:2)]), query = .y, k = 500)) %>%
purrr::set_names(c("df1", "df2"))

R - Saving every dataframe in a list of dataframes

I'd flatten the list:

flatlist <- unlist(df_list, recursive = FALSE)
for (n in names(flatlist)) write.csv(flatlist[[n]], sprintf("%s.csv", n))


Related Topics



Leave a reply



Submit