0

I want call the predict function using different models to extract its predicted value. I tried using paste0 to call the right model but it doesn't work for example:

model0 = lm(mpg ~ cyl + disp, data = mtcars)
model1 = lm(mpg ~ hp + drat, data = mtcars)
model2 = lm(mpg ~ wt + qsec, data = mtcars)

testdat0 = data.frame(cyl = 6, disp = 200)
testdat1 = data.frame(hp = 100, drat = 4)
testdat2 = data.frame(wt = 4, qsec = 20)

res = NULL
for (i in 1:3) {
  res = rbind(res, c(i-1, predict(paste0('model',i-1), newdata = paste0('testdat0',i-1))))
}

to do it manually

rbind(c(0, predict(model0, newdata = testdat0)), 
      c(1, predict(model1, newdata = testdat1)), 
      c(2, predict(model2, newdata = testdat2)))

              1
[1,] 0 21.02061
[2,] 1 24.40383
[3,] 2 18.13825

Another way I thought of doing this was to put the models and testdata in 2 separate list() and use a for loop to call them but that also didn't work. Is there another way of doing this or am I doing something wrong.. TIA

3
  • the predict you do only extracts the value for the first category (in your example the Mazda RX4) since you c() it to an index number. Is this what you want to do? Commented Apr 29, 2019 at 6:31
  • Maybe: lm<-list(model0,model1,model2);lt<-list(testdat0,testdat1,testdat2);purrr::map2(lm,lt,predict) or mapply(predict, lm,lt) Commented Apr 29, 2019 at 6:42
  • Yes it was intentional. This is just a silly example showing model comparison to predict mpg Commented Apr 29, 2019 at 6:58

2 Answers 2

2

My solution to your problem using a list and sapply so we don't need to define an external variable and rbind() to it over and over.

model0 = lm(mpg ~ cyl + disp, data = mtcars)
model1 = lm(mpg ~ hp + drat, data = mtcars)
model2 = lm(mpg ~ wt + qsec, data = mtcars)

testdat0 = data.frame(cyl = 6, disp = 200)
testdat1 = data.frame(hp = 100, drat = 4)
testdat2 = data.frame(wt = 4, qsec = 20)

#make list from sample data
data <- list(dat0=list(model=model0,test=testdat0),
             dat1=list(model=model1,test=testdat1),
             dat2=list(model=model2,test=testdat2))

#sapply over list, automatically converts to matrix
res <- sapply(data,function(dat) predict(dat$model,newdata=dat$test) )

> res
  dat0   dat1   dat2 
21.02061 24.40383 18.13825 

Sign up to request clarification or add additional context in comments.

4 Comments

This is certainly a much better method than using rbind() over and over again.
@AkselA Thanks for the heads-up fixed the comment.
sorry if this is a stupid question but I'm confused about the output of your 'res', what is it doing/showing? the expect mpg for each car based on the 3 models & data?
I'm sorry. I made a code error (data instead of dat) and did not notice that the result ist nonsensical (it's very early here). I fixed it and it should now show the exprected mpg for the values in testdat. // PS: To clarify what happened here: If you do not provide a newdata argument, predict will predict the original data with the model. Since data$test does not exist, R will handle the function as if newdata was omitted instead of throwing an error (I really don't like this behaviour). So it just predicted the data in mtcars with the model.
1

To make your for loop work, you can make the below changes:

res = NULL
for (i in 1:3) {
  res = rbind(res, c(i-1, predict(eval(as.name(paste0('model',i-1)))), newdata = eval(as.name(paste0('testdat',i-1)))))
}

Comments

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.