web-dev-qa-db-fra.com

Passer un vecteur de variables dans la formule lm ()

J'essayais d'automatiser une partie de mon code pour que la programmation devienne moins fastidieuse.

En gros, j'essayais de faire une sélection pas à pas de variables en utilisant fastbw() dans le fichier rms package. J'aimerais passer la liste des variables sélectionnées par fastbw() dans une formule sous la forme y ~ x1+x2+x3, "x1" "x2" "x3" étant la liste des variables sélectionnées par fastbw().

Voici le code que j'ai essayé et qui n'a pas fonctionné

olsOAW0.r060 <- ols(roll_pct~byoy+trans_YoY+change18m, 
                    subset= helper=="POPNOAW0_r060", 
                    na.action = na.exclude, 
                    data = modelready)

OAW0 <- fastbw(olsOAW0.r060, rule="p", type="residual", sls= 0.05)

vec <- as.vector(OAW0$names.kept, mode="any")

b <- paste(vec, sep ="+") ##I even tried b <- paste(OAW0$names.kept, sep="+")

bestp.OAW0.r060 <- lm(roll_pct ~ b , 
                      data = modelready, 
                      subset = helper =="POPNOAW0_r060",    
                      na.action = na.exclude)

Je suis nouveau chez R et je n'ai toujours pas suivi la courbe d'apprentissage abrupte, alors veuillez nous excuser pour les erreurs de programmation évidentes. 

36
Anand

Tu y es presque. Vous devez juste paste la entière formule ensemble, quelque chose comme ceci:

paste("roll_pct ~ ",b,sep = "")

contraignez-le à une formule réelle en utilisant as.formula puis transmettez that à lm. Techniquement, je pense que lm peut contraindre une chaîne de caractères elle-même, mais le contraindre vous-même est généralement plus sûr. (Certaines fonctions qui n'attendent que des formules ne feront pas la contrainte, d'autres le feront.)

52
joran

Vous devrez en fait utiliser collapse au lieu de seb pour définir b. 

b <- paste(OAW0$names.kept, collapse="+")

Ensuite, vous pouvez le mettre en réponse Joran

paste("roll_pct ~ ",b,sep = "")

ou simplement utiliser:

paste("roll_pct ~ ",paste(OAW0$names.kept, collapse="+"),sep = "")
18
cconnell

J'ai rencontré un problème similaire aujourd'hui, si vous voulez le rendre encore plus générique sans qu'il soit nécessaire d'avoir un nom de classe fixe, vous pouvez utiliser 

frmla <- as.formula(paste(colnames(modelready)[1], paste(colnames(modelready)[2:ncol(modelready)], sep = "", 
                              collapse = " + "), sep = " ~ "))

Cela suppose que vous ayez une variable de classe ou la variable dépendante dans la première colonne, mais que l'indexation peut être facilement basculée vers la dernière colonne en tant que:

frmla <- as.formula(paste(colnames(modelready)[ncol(modelready)], paste(colnames(modelready)[1:(ncol(modelready)-1)], sep = "", 
                              collapse = " + "), sep = " ~ "))

Continuez ensuite avec lm en utilisant:

bestp.OAW0.r060 <- lm(frmla , data = modelready, ... )
8
discipulus

Si vous cherchez quelque chose de moins verbeux:

fm <- as.formula( paste( colnames(df)[i], ".", sep=" ~ ")) 
                                      # i is the index of the outcome column

Ici c'est dans une fonction:

getFormula<-function(target, df) {

  i <- grep(target,colnames(df))
  as.formula(paste(colnames(df)[i], 
                   ".", 
                   sep = " ~ "))
}
fm <- getFormula("myOutcomeColumnName", myDataFrame)
rp <- rpart(fm, data = myDataFrame) # Use the formula to build a model
1
Travis Heeter

juste pour simplifier et rassembler les réponses ci-dessus, basées sur une fonction

my_formula<- function(colPosition, trainSet){
    dep_part<- paste(colnames(trainSet)[colPosition],"~",sep=" ")
    ind_part<- paste(colnames(trainSet)[-colPosition],collapse=" + ")
    dt_formula<- as.formula(paste(dep_part,ind_part,sep=" "))
    return(dt_formula)
}

Pour l'utiliser:

my_formula( dependent_var_position, myTrainSet)
0
user3169330