0

I need to store the results of my loop in a data frame but i can't figure it out. I got the loop working as shown below.

Pasta_pesto <- list(ingredienten = c("spaghetti","basilicum","pijnboompitten","pesto"))
Broccoli_spinaziesoep <- list(ingredienten = c("broccoli", "spinazie"))
Romige_kipcurry <- list(ingredienten = c("zilvervliesrijst", "sperziebonen", "kip", "curry"))

recepten <- list(Pasta_pesto, Broccoli_spinaziesoep, Romige_kipcurry)

food_box <- list("spaghetti", "pesto", "kip", "curry")

for (i in recepten) {
   for (e in i) {
      for (j in e) {
          for (k in food_box) {
            if (k == j){
            print(c("true", j, k))
          }
            else {
            print(c("false", j, k))}}}}}

rights now its prints out true or false but the end result should be a table with the following columns: recepten, count of true per recept, total items in recept list. as you can see the amount of true's have to be count and stored.

I hope any of you can help me.

Uwe
  • 41,420
  • 11
  • 90
  • 134
Anonymous
  • 3
  • 2
  • Why do you need that many for-loops? You can write data to a data.frame by selecting the cell of the data.frame `df[1,2]` and then assigning the value with `<-`. The data.frame should be created before and you can also use named columns. – hannes101 Jan 10 '20 at 14:46
  • it's a school assignment and we're working with loops and lists, because we have lists in lists we need to create a couple of loops. I'll give it a try! – Anonymous Jan 10 '20 at 14:55
  • 1
    You can hardly have a column with the names of the _recepten_, since those names are not stored in a variable, but rather variable names themselves. – Armali Jan 10 '20 at 15:12
  • Wouldn't "total items in recept list" always be 3, `recepten <- list(Pasta_pesto, Broccoli_spinaziesoep, Romige_kipcurry)`? – Conner M. Jan 10 '20 at 15:25
  • unfortunately not, is has to by dynamic so it has to work regardless of the number of items in the list – Anonymous Jan 10 '20 at 15:38

3 Answers3

2

There was a bug when no words were found fixed it

library(tidyverse)

Pasta_pesto <- list(Pasta_pesto = c("spaghetti","basilicum","pijnboompitten","pesto"))
Broccoli_spinaziesoep <- list(Broccoli_spinaziesoep = c("broccoli", "spinazie"))
Romige_kipcurry <- list(Romige_kipcurry = c("zilvervliesrijst", "sperziebonen", "kip", "curry"))

recepten <- list(Pasta_pesto, Broccoli_spinaziesoep, Romige_kipcurry)

food_box<- list("spaghetti", "pesto", "kip", "curry", "basilicum", "pijnboompitten")

operation <- function(x,y){
  count_ingredients <- length(x)
  ingredient_in_food_box  <- x %in% y
  count_of_true <-  ingredient_in_food_box %>% sum
  missing_ingredients <- x[!ingredient_in_food_box] %>% str_flatten(collapse = "_") %>% list
  list(count_ingredients = count_ingredients,
       count_of_true = count_of_true,
       which_ingredient =  missing_ingredients)

}

recepten %>%
  flatten() %>% 
  map_dfr(~ operation(.,food_box),.id = "receipen") %>% 
  mutate(show = which_ingredient %>% as.character())
#> # A tibble: 3 x 5
#>   receipen       count_ingredien… count_of_true which_ingredient show           
#>   <chr>                     <int>         <int> <list>           <chr>          
#> 1 Pasta_pesto                   4             4 <chr [0]>        character(0)   
#> 2 Broccoli_spin…                2             0 <chr [1]>        broccoli_spina…
#> 3 Romige_kipcur…                4             2 <chr [1]>        zilvervliesrij…

Created on 2020-01-15 by the reprex package (v0.3.0)

Bruno
  • 4,109
  • 1
  • 9
  • 27
  • This is amazing! to you maybe also now a way to see which items are missing? – Anonymous Jan 10 '20 at 15:51
  • What do you define as missing missing in the food_box for the recipe or in the recipe for the food_box? – Bruno Jan 10 '20 at 15:58
  • Sorry for the late response. It almost did... when i change the food_box list i get an error: "Error: Argument 3 must be length 1, not 0" any ideas? i figured it comes form the 'score' calculation. – Anonymous Jan 15 '20 at 13:11
  • This was a bug caused by a complete recipe (no missing ingredients) solved it – Bruno Jan 15 '20 at 16:56
1

The easiest way to do this is using rbind(). It's also very slow and loops in R aren't recommended for this type of thing (merge or join would be better). However, for homework it makes sense because you need to understand how the logic works before you start using tools to do it faster.

How to create an empty dataframe:

df1 <- data.frame(contains = character(),
                  recepten = character(),
                  foodbox = character()
       )

Creating an empty dataframe makes it easier to use in a loop because you don't have to treat the first loop (when there is no data or dataframe) differently from later loops.

Then any time you want to add a row to the dataframe you can create a new dataframe with a single row of data and then:

df1 <- rbind(df1,df2)

It's slow, but it shows the logic. I'm going to leave how/where to put it into the loop to you since this is homework.

Adam Sampson
  • 1,971
  • 1
  • 7
  • 15
  • 1
    Hint: don't create an empty dataframe inside your loop or you'll be overwriting your full dataframe. – Adam Sampson Jan 10 '20 at 15:09
  • 1
    I agree with Adam_Sampson, this is the basic approach for building the initial dataframe. There is a more detailed discussion here: https://stackoverflow.com/questions/28467068/add-row-to-dataframe. After you have the initial df, you can use a group_by method along with the count operator to get your final summary - also as a df. – Conner M. Jan 10 '20 at 15:28
  • Thanks for your input. I was able to make a df but i cant get it to work... which is mainly the reason i asked the question :) – Anonymous Jan 10 '20 at 15:36
1

Here is a base R solution

lst <- unlist(recepten,recursive = F)
dfout <- data.frame(
  recp = c("Pasta_pesto", "Broccoli_spinaziesoep", "Romige_kipcurry"),
  ing_num = lengths(lst),
  cnt_true = sapply(lst,function(x) sum(x %in% food_box)))

such that

> dfout
                   recp ing_num cnt_true
1           Pasta_pesto       4        2
2 Broccoli_spinaziesoep       2        0
3       Romige_kipcurry       4        2
ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81