Search code examples
rfor-loopappendevalvariable-names

R - Appending to lists with names l_A, l_B, l_C ... etc. using for loops and built-in LETTERS


I've generated empty lists corresponding to every letter of the alphabet. The names of the lists take the form l_A, l_B, ... I also have a one-column data frame populated with strings (all lowercase, no symbols). I want to sort these strings by their first letter into the corresponding list, e.g., the word "aardvark" would go in list l_A.

I'm having problems calling the correct list when iterating through the data frame. This is my attempt to sort using for loops. For the example, I'm using a random list of words (all lowercase) built using the library "OpenRepGrid" to build the starting data frame.

install.packages("OpenRepGrid")
library(OpenRepGrid)

# random words data frame
df <- data.frame(tolower(randomWords(100)))

# lists for each letter
for (i in 1:26){
    nam <- paste0("l_", LETTERS[i])
    assign(nam, list()) 
    }

# sorting words in data frame into lists using for loops
for (i in 1:nrow(df)){
  for (j in 1:26){
    if (substr(df[i, 1], 1, 1) == letters[j]){
      append(eval(as.name(paste0("l_", LETTERS[j]))), df[i, 1])
    }
  }
}

The empty lists generate correctly and I don't get any errors, but all of my lists end up still being empty. This is leading me to think the issue is trying to call the lists using eval(as.name(paste0("l_", LETTERS[j]))). I know I could write if statements for each list rather than using a nested for loop, but this is cumbersome with 26 lists!

Even if you have a much more elegant method, I'd still like to know what I need to do for my current method to work as well as your own recommended solutions.

TIA!


Solution

  • OP is creating NULL list in a loop. It can be done in more easier ways as well

    > l_A
    list()
    

    In the second loop, we need to get the value of the list created for appending and assign back to the same object

    for (i in 1:nrow(df)){
      for (j in 1:26){
        if (substr(df[i, 1], 1, 1) == letters[j]){
          tmp <- paste0("l_", LETTERS[j])
          assign(tmp, append(get(tmp), df[i, 1]))
        }
      }
    }
    

    -checking

    > l_A
    [[1]]
    [1] "as"
    
    [[2]]
    [1] "airplane"
    
    [[3]]
    [1] "as"
    
    [[4]]
    [1] "away"
    
    [[5]]
    [1] "airplane"
    
    [[6]]
    [1] "airplane"
    ...