3

How do I return an object from a function, rather than the output provided when you call the object?

best.mod <- function(d){
  m1 <- lm(Sepal.Length~Sepal.Width, d)
  m2 <- lm(Sepal.Length~Sepal.Width + I(Sepal.Width^2), d)
  ifelse(AIC(m1) < AIC(m2), m1, m2)
}

mod <- best.mod(iris[iris$Species == "setosa",])
class(mod)

2 Answers 2

5

The problem comes from using ifelse. This is meant for vectorised comparisons. A standard if ... else is better here:

best.mod <- function(d){
  m1 <- lm(Sepal.Length~Sepal.Width, d)
  m2 <- lm(Sepal.Length~Sepal.Width + I(Sepal.Width^2), d)
  if(AIC(m1) < AIC(m2)) return(m1) else return(m2)
}

mod <- best.mod(iris[iris$Species == "setosa",])
class(mod)
[1] "lm"

Note the warning from ?ifelse:

The mode of the result may depend on the value of test (see the examples), and the class attribute (see oldClass) of the result is taken from test and may be inappropriate for the values selected from yes and no.

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

2 Comments

I think @James just got there first. Thank you both - I didn't know that about ifelse
I think it's simpler and better without return, like this:if(AIC(m1) < AIC(m2)) m1 else m2
3

ifelse is not really meant for this kind of usage, simply use if and else for this:

best.mod <- function(d){
  m1 <- lm(Sepal.Length~Sepal.Width, d)
  m2 <- lm(Sepal.Length~Sepal.Width + I(Sepal.Width^2), d)
  if(AIC(m1) < AIC(m2)) m1 else m2
}

mod <- best.mod(iris[iris$Species == "setosa",])
class(mod)

ifelse is meant for this kind of things:

vec = runif(100)
ifelse(vec < 0.5, NA, vec)

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.