0

I'm running several models and functions with the models. I need to apply values from a list to a default R function, e.g., modelFit() My idea is to run the same function to several models and compile the results after.

I'm trying to use loops and the Family of 'apply' functions in R, but with no success.

#package drc is necessary
library(drc)
#my data
rates <- c(.1,.1,.1,1,1,1,10,10,10,100,100,100,1000,1000,1000,.1,.1,.1,1,1,1,10,10,10,100,100,100,1000,1000,1000)
prod <- c("A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B")
resp <- c(.295,.32,.301,.155,.1501,.148,.05,.03,.044,.002,.001,.0015,.001,.0005,.0003,.312,.337,.299,.265,.2501,.248,.102,.103,.114,.02,.01,.015,.003,.0002,.0007)
data.test <- data.frame(rates,prod,resp) #my data frame

#my models
m1 <- drm(resp~rates, fct=LL.4(), data=data.test[data.test$prod=="A",])
m2 <- drm(resp~rates, fct=LL.4(), data=data.test[data.test$prod=="B",])

#lack of fit test
modelFit(m1)
modelFit(m2)

#I can get the modelFit p-values this way:
modelFit(m1)$"p value"[2]
modelFit(m2)$"p value"[2]


#I have several models. I want to create a loop to give me only the p value for each model fit. I want to use that for other information given by the summaries and function

#list of models
modelsList <- c("m1","m2")

#I can print the strings with the loop
for(i in modelsList){
  print(i)
  }

My idea was to use the strings to add information for the default 'drc' function modelFit(). The result would be a list with all p values from all the results in the loop, but I'm getting the error:

Error: $ operator is invalid for atomic vectors

#Not working
for(i in modelsList){
  modelFit(i)$"p value"[2]
  }

#Error
# Error: $ operator is invalid for atomic vectors

#Trying to use lapply
#Following this logic
lapply(modelsList, function(x) print(x))
#I could not get the results
lapply(modelsList, function(x) modelFit(x)$"p value"[2])

With the results, I'd continue and I'd create a data.frame with all the models and respective p values.

Danilo G.
  • 80
  • 1
  • 7

2 Answers2

0

good to see you, Danilo

I think you missed drm function.


modelsList <- c("m1","m2")
prod = c("A","B")
type = data.frame(modelsList,
                  prod)
#I can print the strings with the loop
for(i in modelsList){
  print(i)
}


for(i in modelsList){
  model_Prod = type[modelsList == i,]$prod
  drm_result<-drm(resp~rates, fct=LL.4(), data=data.test[data.test$prod==model_Prod,])
  print(modelFit(drm_result)$"p value"[2])
}

# lapply
lapply(modelsList, function(x) {
  model_Prod = type[modelsList == x,]$prod
  x<-drm(resp~rates, fct=LL.4(), data=data.test[data.test$prod==model_Prod,])
  modelFit(x)$"p value"[2]
}

)
Steve Lee
  • 786
  • 3
  • 10
  • Steve, thank you. It is really doing what I wanted. I thought it would be easiar as I had the models called/stored already in the code. Now I'm going to try to compile all the results from the loop in a data.frame. I hope I'll not turn into another question... – Danilo G. Aug 02 '19 at 11:02
0

Continuing, after Steve Lee inputs, I could generate a data.frame with all results I got from the loop:

#source of information:
#https://stackoverflow.com/questions/25285570/invalid-factor-level-with-rbind-to-data-frame
#df.results will be a data.frane with headers = "Model" and "ModelFit_pvalue""
df.results <- NULL
#Loop to print only specif information requested from function and add it to a data frame
for(i in modelsList){
  model_Prod = type[modelsList == i,]$prod
  drm_result<-drm(resp~rates, fct=LL.4(), data=data.test[data.test$prod==model_Prod,])
  #print(i)
  #print(modelFit(drm_result)$"p value"[2])
  modelpvalue <- modelFit(drm_result)$"p value"[2] #store p values in a variable
  de <- data.frame("Model"=i,"ModelFit_pvalue"= modelpvalue)
  df.results = rbind(df.results,de)
}
df.results

#df.results output:
  Model ModelFit_pvalue
1    m1       0.2346460
2    m2       0.5757368
Danilo G.
  • 80
  • 1
  • 7