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

Time:12-15

Reproducible code:

    Meal <- function(name, ingredients, time_to_cook = NA, time_of_day = "Dinner", cuisine = NA) {
m <- list(name = name, ingredients = ingredients, time = time_to_cook, meal = time_of_day, cuisine = cuisine)
  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"))

rbind(data.frame(pizza), data.frame(burritos))

      name    ingredients time   meal cuisine
1    Pizza          Flour <NA> Dinner    <NA>
2    Pizza  Tinned Tomato <NA> Dinner    <NA>
3    Pizza      Mozarella <NA> Dinner    <NA>
4    Pizza         Garlic <NA> Dinner    <NA>
5  Burrito       Tortilla Fast Dinner Mexican
6  Burrito Chicken Breast Fast Dinner Mexican
7  Burrito     Sour Cream Fast Dinner Mexican
8  Burrito         Pepper Fast Dinner Mexican
9  Burrito          Onion Fast Dinner Mexican
10 Burrito    Chili Paste Fast Dinner Mexican

The behavior I would prefer is if ingredients was not converted into long format, ie keep Ingredients as a list, rather than one row for each ingredient. Is there any way I can get that behavior?

I don't want to go all the way and use relational databases, was wondering if there is a simple way to handle this.

CodePudding user response:

tibble

You could store them as a tibble which are very good at storing list columns, just by amending Meal().

library(tibble)

Meal <- function(name, ingredients, time_to_cook = NA, time_of_day = "Dinner", cuisine = NA) {
  m <- tibble(name = name, ingredients = list(ingredients), time = time_to_cook, meal = time_of_day, cuisine = cuisine)
  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"))

rbind(pizza, burritos)
#> # A tibble: 2 × 5
#>   name    ingredients time  meal   cuisine
#>   <chr>   <list>      <chr> <chr>  <chr>  
#> 1 Pizza   <chr [4]>   <NA>  Dinner <NA>   
#> 2 Burrito <chr [6]>   Fast  Dinner Mexican

nesting from original solution

Or you can keep your original solution entirely and just convert to a tibble later by using nest to turn ingredients back into a list.

library(tidyr)

rbind(data.frame(pizza), data.frame(burritos)) %>%
  nest(ingredients = ingredients)
#> # A tibble: 2 × 5
#>   name    time  meal   cuisine ingredients     
#>   <chr>   <chr> <chr>  <chr>   <list>          
#> 1 Pizza   <NA>  Dinner <NA>    <tibble [4 × 1]>
#> 2 Burrito Fast  Dinner Mexican <tibble [6 × 1]>

base R

Last, if you want to stick to base R, you can use I(list()) like in @Akrun's comment.

Meal <- function(name, ingredients, time_to_cook = NA, time_of_day = "Dinner", cuisine = NA) {
  m <- data.frame(name = name, ingredients = I(list(ingredients)), time = time_to_cook, meal = time_of_day, cuisine = cuisine)
  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"))
  
rbind(pizza, burritos)
#>      name  ingredients time   meal cuisine
#> 1   Pizza Flour, T.... <NA> Dinner    <NA>
#> 2 Burrito Tortilla.... Fast Dinner Mexican

CodePudding user response:

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

  • Related