0

I need to test a suite of argument conditions in order to find the best model (using the drc package). That is, I'd like to store function arguments in a list and then call them into the drm() function. The drc package has a function (mselect()) to do this, but it has been known to fail for unknown reasons (https://www.reddit.com/r/Rlanguage/comments/a1bu44/any_idea_what_im_doing_wrong_with_the_mselect/).


Example Data

library(drc) # This also loads in the S.alba data
data(S.alba)

head(S.alba)
  Dose  Herbicide DryMatter
1    0 Glyphosate       4.7
2    0 Glyphosate       4.6
3    0 Glyphosate       4.1
4    0 Glyphosate       4.4
5    0 Glyphosate       3.2
6    0 Glyphosate       3.0

Failed Attempt

# List of function arguments to be assessed e.g. drm(...fct = W1.4(fixed = c(NA, 0.1, NA, NA)
model_list <- list(curve = c(W1.4(fixed = c(NA, 0.1, NA, NA)),
                             LL.4(fixed = c(NA, 0.1, NA, NA))))

# Failed function, attempting to return a list of results
model_select <- function(data, mlist){
    model =  data %>%
        drm(DryMatter ~ Dose, Herbicide, data = . , fct = mlist)
    metric = AIC(model)
    return(metric)
}
model_select(data = S.alba, mlist = model_list)

Error in drm(DryMatter ~ Dose, Herbicide, data = ., fct = mlist) : First entry in list to 'fct' NOT a function

Semi-Working Attempt

model_select_2 <- function(data){
    model =  data %>%
        drm(DryMatter ~ Dose, Herbicide, data = . , fct = W1.4(fixed = c(NA, 0.1, NA, NA)))
    metric = AIC(model)
    return(metric)
}
model_select_2(data = S.alba)

model_select_2(data = S.alba)
[1] 106.9226

Desired Output

model_select(data = S.alba, mlist = model_list)
[1] W1.4-106.9226
[2] LL.4-99.54702
TheSciGuy
  • 1,154
  • 11
  • 22

1 Answers1

1

Part of the problem is how you are creating model_list. You want to combine those values with list() rather than c(). The latter tried to combine them into the same object.

The next thing you can do is sapply over the list of curves to get the result for each input. A working example would be

model_list <- list(curve = list(W1.4(fixed = c(NA, 0.1, NA, NA)),
                             LL.4(fixed = c(NA, 0.1, NA, NA))))
model_select <- function(data, mlist){
   sapply(mlist$curve, function(curve){
      model <- drm(DryMatter ~ Dose, Herbicide, data = data , fct = curve)
      metric = AIC(model)
   })
}
model_select(data = S.alba, mlist = model_list)
# [1] 106.92259  99.54702
MrFlick
  • 195,160
  • 17
  • 277
  • 295
  • Ahhhh! I've never would've thought to make a list of lists...would it be possible to add the curve names to the results so I would know which model is best? (See updated "Desired Output") – TheSciGuy Feb 17 '20 at 17:24
  • Well, it's not super easy unless you name the elements in your sub-list. It's kind of messy to guess the names from function calls otherwise. Then you could paste that data in to the result if you like. – MrFlick Feb 17 '20 at 17:28