Search code examples
rlistfor-loopassign

for loop with lists R


I want to create two lists of data frames in a for loop, but I cannot use assign:

dat <- data.frame(name = c(rep("a", 10), rep("b", 13)),
                  x = c(1,3,4,4,5,3,7,6,5,7,8,6,4,3,9,1,2,3,5,4,6,3,1),
                  y = c(1.1,3.2,4.3,4.1,5.5,3.7,7.2,6.2,5.9,7.3,8.6,6.3,4.2,3.6,9.7,1.1,2.3,3.2,5.7,4.8,6.5,3.3,1.2))

a <- dat[dat$name == "a",]
b <- dat[dat$name == "b",]

samp <- vector(mode = "list", length = 100)
h <- list(a,b)
hname <- c("a", "b")

for (j in 1:length(h)) {
  for (i in 1:100) {
    samp[[i]] <- sample(1:nrow(h[[j]]), nrow(h[[j]])*0.5)
    assign(paste("samp", hname[j], sep="_"), samp[[i]])
  }
}

Instead of lists named samp_a and samp_b I get vectors which contain the result of the 100th sample. I want to get a list samp_a and samp_b, which have all the different samples for dat[dat$name == a,] and dat[dat$name == a,].

How could I do this?


Solution

  • How about creating two different lists and avoiding using assign:

    Option 1:
    
    # create empty list
    samp_a <-list()
    samp_b <- list()
    
    for (j in seq(h)) {
    
        # fill samp_a list
        if(j == 1){
            for (i in 1:100) {
                samp_a[[i]] <- sample(1:nrow(h[[j]]), nrow(h[[j]])*0.5)
            }
          # fill samp_b list
        } else if(j == 2){
            for (i in 1:100) {
                samp_b[[i]] <- sample(1:nrow(h[[j]]), nrow(h[[j]])*0.5)
            }
        }
    }
    

    You could use assign too, shorter answer:

    Option 2:
    
    for (j in seq(hname)) {
        l = list()
        for (i in 1:100) {
            l[[i]] <- sample(1:nrow(h[[j]]), nrow(h[[j]])*0.5)
        }
        assign(paste0('samp_', hname[j]), l)
        rm(l)
    }