Search code examples
rlistloopsfor-loopstore

how to store a loop over columns in a list with R


Think I have an easy question but I was not able to find my mistake so far. I want to create a single elimination tournament with 32 participants. To do so I created 4 groups with 8 Players and now a want to build the matchups with a for loop and store them into a list, but its not working as I want :(

>groups
            A        B        C        D
    1 Player1  Player9 Player17 Player25
    2 Player2 Player10 Player18 Player26
    3 Player3 Player11 Player19 Player27
    4 Player4 Player12 Player20 Player28
    5 Player5 Player13 Player21 Player29
    6 Player6 Player14 Player22 Player30
    7 Player7 Player15 Player23 Player31
    8 Player8 Player16 Player24 Player32

now I want to store them as pairs in their groups to have an easy access to calculate winning props later on. Should look like this for the first Group A

>teams.group.A <- matrix(groups$A,nrow = 2,ncol = 4)
>teams.group.A
     [,1]      [,2]      [,3]      [,4]     
[1,] "Player1" "Player3" "Player5" "Player7"
[2,] "Player2" "Player4" "Player6" "Player8"

my idea for the loop was:

groupnames <- colnames(groups)

mylist <- list()
for(i in groupnames){
  mylist[[i]] <- matrix(groups$i,nrow = 2,ncol = 4)
}
mylist

I get the error, that "data" must be a vector type?

Thx, if you can help me here!


Solution

  • Assuming your groups variable is a dataframe, you can easily use lapply and you'll get a nice named list as a result:

    # generate data
    players <- paste0('Player',1:32)
    grps <- data.frame(A=players[1:8],B=players[9:16],C=players[17:24],D=players[25:32])
    
    
    #smoother version as suggested by P Lapointe:
    mylist <- lapply(grps,matrix,nrow=2)
    
    # more verbose
    # mylist <- lapply(grps,function(x) matrix(x,ncol = 4))
    
    
    # output
    
    > mylist
    $A
         [,1]      [,2]      [,3]      [,4]     
    [1,] "Player1" "Player3" "Player5" "Player7"
    [2,] "Player2" "Player4" "Player6" "Player8"
    
    $B
         [,1]       [,2]       [,3]       [,4]      
    [1,] "Player9"  "Player11" "Player13" "Player15"
    [2,] "Player10" "Player12" "Player14" "Player16"
    
    $C
         [,1]       [,2]       [,3]       [,4]      
    [1,] "Player17" "Player19" "Player21" "Player23"
    [2,] "Player18" "Player20" "Player22" "Player24"
    
    $D
         [,1]       [,2]       [,3]       [,4]      
    [1,] "Player25" "Player27" "Player29" "Player31"
    [2,] "Player26" "Player28" "Player30" "Player32"
    

    To bring it back into a single dataframe, you can use do.call(cbind,mylist):

    > do.call(cbind,mylist)
         [,1]      [,2]      [,3]      [,4]      [,5]       [,6]       [,7]       [,8]       [,9]       [,10]      [,11]     
    [1,] "Player1" "Player3" "Player5" "Player7" "Player9"  "Player11" "Player13" "Player15" "Player17" "Player19" "Player21"
    [2,] "Player2" "Player4" "Player6" "Player8" "Player10" "Player12" "Player14" "Player16" "Player18" "Player20" "Player22"
         [,12]      [,13]      [,14]      [,15]      [,16]     
    [1,] "Player23" "Player25" "Player27" "Player29" "Player31"
    [2,] "Player24" "Player26" "Player28" "Player30" "Player32"