1

I am doing a number of regression's using a for loop, and want to store the results in a list. Normally, I would use assign:

AllChicks <- levels(ChickWeight$Chick) #example database

for (i in AllChicks) {
  DataSub <- subset(ChickWeight, Chick==i)
  Fit <- lm(DataSub$Time ~ DataSub$weight)
  assign(paste("Regr_",i,sep=""),Fit)
  assign(paste("Sum_",i,sep=""),summary(Fit))
  assign(paste("Residual_",i,sep=""),residuals(Fit))
}

But now i would like to put the Fit, summary and Residuals in a list per Chick, so named Chick1, Chick2, Chick3 etc. I have found the following commands to work for the first object:

assign(paste("Chick",i,sep=""),list(Fit))
do.call("<-",list(paste("Chick",i,sep=""),list(Fit)))

But then off course the first list object is overwritten by:

assign(paste("Chick",i,sep=""),list(summary(Fit)))

And I've tried these, but they make a variable named "Chick1[[2]]", in stead of taking the second object from the list.

assign(paste("Chick",i,"[[2]]",sep=""),list(summary(Fit)))
do.call("<-",list(paste("Chick",i,"[[2]]",sep=""),list(summary(Fit))))

I have a feeling it must be very simple, but can't figure it out...

1
  • 1
    look at dominus approach. It is better to use a list behaviour rather than spoiling the global envrionment with tones of variable. Commented Apr 30, 2015 at 10:23

1 Answer 1

3

Here's an approach using lapply and split which will return a list with one element per chick and each chick-element in the list is itself a list with three components: the model, model summary and residuals.

res <- lapply(split(ChickWeight, paste0("Chick", ChickWeight$Chick)), function(x) {
  Fit <- lm(x$Time ~ x$weight)
  list(
    Regr = Fit,
    Sum = summary(Fit),
    Residual = residuals(Fit)
  )
})

Now, to look at the results, e.g. for "Chick1" you can do:

> res$Chick1
$Regr

Call:
lm(formula = x$Time ~ x$weight)

Coefficients:
(Intercept)     x$weight  
     -2.487        0.120  


$Sum

Call:
lm(formula = x$Time ~ x$weight)

Residuals:
    Min      1Q  Median      3Q     Max 
-2.5545 -1.1895  0.2818  1.3340  1.7635 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept) -2.486826   0.980399  -2.537   0.0295 *  
x$weight     0.120031   0.007868  15.255 2.97e-08 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 1.507 on 10 degrees of freedom
Multiple R-squared:  0.9588,    Adjusted R-squared:  0.9547 
F-statistic: 232.7 on 1 and 10 DF,  p-value: 2.974e-08


$Residual
          1           2           3           4           5           6           7 
-2.55448776 -1.63476925 -0.59501946  0.80482416  1.36444885  1.32391715  1.76351056 
          8           9          10          11          12 
 1.48291632  0.60216569 -0.03852238 -1.39939812 -1.11958577 

Or, if you want to get only the residuals of chick1, you can do:

> res$Chick1$Residual
          1           2           3           4           5           6           7 
-2.55448776 -1.63476925 -0.59501946  0.80482416  1.36444885  1.32391715  1.76351056 
          8           9          10          11          12 
 1.48291632  0.60216569 -0.03852238 -1.39939812 -1.11958577 

Edit after comment:

I never work with assign so I won't suggest any use of it here either but if you want to use a for loop, you could do it like this (or somehow similar):

chicks <- unique(ChickWeight$Chick)
res <- vector("list", length = length(chicks))

for(i in chicks) {
  DataSub <- ChickWeight[ChickWeight$Chick == i, ]
  Fit <- lm(DataSub$Time ~ DataSub$weight)
  res[[i]] <- list(
    Regr = Fit,
    Sum = summary(Fit),
    Residual = residuals(Fit)
  )
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you (and +1) for this elegant, R-ish answer. However, i would still like to know if there is a way to fill a list by assign or do.call in a for loop. Or is that impossible?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.