cplus
cplus

Reputation: 1115

r multiple for loop aggregate result in matrix

I am trying to do a for loop of 50 times and each time generating three columns and 13 rows of data which I store in a matrix, so the final product should have 13 rows but 150 columns. That is, each time, the for loop result is aggregated to the right of the previous one. Here is my attempt:

predict.data<-matrix(nrow=13,ncol = 150)
for (i in 1:50){
  x <- rnorm(15)
  y <- x + rnorm(15)
  new <- data.frame(x = seq(-3, 3, 0.5))

  for (j in 1:nrow(new)){ 
    predict.data[j,] <- predict(lm(y ~ x), new, interval = "prediction")
    colnames(predict.data) <- paste(c("fit", "lwr","upr"), 1:50)
  }
}

but I get the following error:

  number of items to replace is not a multiple of replacement length

maybe I am missing a point somewhere in the code. I also need to paste the column names consecutively: fit1, lwr1, upr1, fit2, lwr2, upr2, ...

Could somebody help me to correct and adjust this fo

expected result will look like something like:

fit1    lwr1    upr1    fit2    lwr2    upr2    …   fit50   lwr50   upr50
1,81    1,76    1,44    1,22    1,70    1,14    …   1,97    1,45    1,16
1,67    1,46    1,52    1,89    1,43    1,02    …   1,86    1,38    1,69
1,73    1,76    1,53    1,35    1,44    1,74    …   1,92    1,22    1,01
1,72    1,89    1,12    1,55    1,81    1,21    …   1,47    1,79    1,99
1,30    1,30    1,04    1,07    1,07    1,95    …   1,20    1,08    1,59
1,64    1,94    1,73    1,10    1,59    1,28    …   1,89    1,62    1,14
2,00    1,56    1,24    1,10    1,50    1,16    …   1,59    1,25    1,88
1,64    1,03    1,58    1,84    1,57    1,33    …   1,96    1,75    1,01
1,50    1,51    1,64    1,32    1,46    1,10    …   1,71    1,68    1,35
1,94    1,50    1,28    1,64    1,90    1,54    …   1,25    1,51    1,96
1,24    1,67    1,74    1,21    1,29    1,81    …   1,63    1,91    1,82
1,81    1,90    1,28    1,85    1,59    1,13    …   1,55    1,25    1,98
1,35    1,12    1,26    1,52    1,25    1,46    …   1,75    1,84    1,09

new update

I have another problem regarding the case when the new is a matrix and instead of lm i have cv.glmnet from package "glmnet". I only get in the final result one third of the data, that is only 50 columns instead of 150. and the colnames are not right anymore.

Upvotes: 0

Views: 155

Answers (2)

Pierre Lapointe
Pierre Lapointe

Reputation: 16277

With base R. I use cbind

predict.data<-NULL  #empty object
for (i in 1:50){
  x <- rnorm(15)
  y <- x + rnorm(15)
  new1 <- data.frame(x = seq(-3, 3, 0.5))

  for (j in 1:nrow(new1)){
    res <- predict(lm(y ~ x), new1, interval = "prediction")
    colnames(res) <- paste0(c("fit", "lwr","upr"), i)
    predict.data<-cbind(predict.data,res)
  }
}

Upvotes: 0

Nate
Nate

Reputation: 10671

this would work...

library(magrittr) # sorry I like pipes

predict.data <- list() # versitle across data structures

for (i in 1:50){

    x <- rnorm(15)
    y <- x + rnorm(15)
    new <- data.frame(x = seq(-3, 3, 0.5))

    predict.data[[i]] <- predict(lm(y ~ x), new, interval = "prediction") %>%
                     magrittr::set_colnames(., paste0(colnames(.), i))

}

predict.data %<>% do.call(cbind, .) # make your wide matrix

Upvotes: 1

Related Questions