0

I have a dataframe with a random number of quantitative variables. I need write a function that calculate lm for predicting the values of the dependent variable. As predictors, I want to use only those variables that have p.value > 0.05. The function should return linear regression coefficients constructed only for selected predictors as a vector. If there are no such predictors in the data, then the function should returns the warning "There are no normal variables in the data". I write the function, but it does not work.

smart_lm <-  function(x) {
  sl <- apply(x[2:dim(x)[2]], 2, function(x) shapiro.test(x)$p.value)
  my_reg <- lm(as.formula(paste("x[[1]]~",paste(x[2:dim(x)[2]], collapse = "+"))))
  return(ifelse(sl[sl > 0.05], my_reg, "There are no normal variables in the data"))
}
MrFlick
  • 195,160
  • 17
  • 277
  • 295
  • 1
    When asking for help, you should include a simple [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input and desired output that can be used to test and verify possible solutions – MrFlick Jan 26 '18 at 18:39
  • Tip: `lm` is surely more expensive than `ifelse` or `if/else`. Couldn't you invert the logic in your function? – Rui Barradas Jan 26 '18 at 18:48

1 Answers1

0

If I understand correctly, the following should do it.
Note that there is no need for an ifelse and the formula uses the dot . to include all variables of the data argument not yet in the formula, which are all but DF2[[1]].

set.seed(1665)    # Make the results reproducible
n <- 100
x1 <- rnorm(n)
x2 <- rnorm(n, 2, 6)
x3 <- rexp(n)
y <- x1 + x2 + x3 + rnorm(n)

dat <- data.frame(y, x1, x2, x3)

smart_lm <- function(DF){
    sl <- c(NA, sapply(DF[-1], function(x) shapiro.test(x)$p.value))
    DF2 <- DF[, which(sl > 0.05)]
    names(DF2) <- names(DF)[which(sl > 0.05)]
    lm(DF2[[1]] ~ ., data = DF2)
}

smart_lm(dat)
#
#Call:
#lm(formula = DF2[[1]] ~ ., data = DF2)
#
#Coefficients:
#(Intercept)           x1           x2  
# -3.331e-17    1.000e+00    9.593e-18
Rui Barradas
  • 70,273
  • 8
  • 34
  • 66