Loop to label tokens with their corresponding value in r

Viewed 38

This should be pretty simple; however, I can't get it right. I got the followin list:

list <- list(c("sofa", "couch"), 
         c("fridge"),
         c("desk", "table", "brown"),
         c("window", "clean"),
         c("speaker"))

Which I am trying to convert to the following format (as a dataframe)

table <- data.frame(word = c("sofa", "couch", "fridge", "desk", "table", "brown", "window", "clean", "speaker"),
                label = c("sofa couch", "sofa couch", 
                          "fridge", 
                          "desk table brown", "desk table brown", "desk table brown",
                          "window clean",
                          "window clean",
                          "speaker"))

I created this loop which makes sense to me but it is not working. I can't figure out why or if this is the best way of doing it

table <- data.frame(word = character(), label = character(), stringsAsFactors = FALSE)
value <- 0

for(i in 1:length(list)){
  for(j in 1:length(list[[i]])){
    value <- c(list[[i]][j], str_c(list[[i]], collapse = " "))
    table <- rbind(table, value)
  }
}
3 Answers

In base R, you could unlist the list to get word and repeat the concatenated elements of each list based on their lengths.

data.frame(word = unlist(list), 
           label = rep(sapply(list, paste, collapse = " "), lengths(list)))

#     word            label
#1    sofa       sofa couch
#2   couch       sofa couch
#3  fridge           fridge
#4    desk desk table brown
#5   table desk table brown
#6   brown desk table brown
#7  window     window clean
#8   clean     window clean
#9 speaker          speaker

Another option is stack

stack(setNames(list, sapply(list, paste, collapse = " ")))
#   values              ind
#1    sofa       sofa couch
#2   couch       sofa couch
#3  fridge           fridge
#4    desk desk table brown
#5   table desk table brown
#6   brown desk table brown
#7  window     window clean
#8   clean     window clean
#9 speaker          speaker

While quickly rewritting my question I found out what is wrong with the code. However, the solutions provided by Ronak and markus before are more compact and make more sense.

To do it with the loop I found out that some parameters were missing

for(i in 1:length(list)){
  for(j in 1:length(list[[i]])){
    value <- data.frame(word = list[[i]][j], label = str_c(list[[i]], collapse = " "), stringsAsFactors = FALSE)
    table <- rbind(table, value)
  }
}
Related