web-dev-qa-db-fra.com

Comment écrire succinctement une formule avec plusieurs variables d'un bloc de données?

Supposons que j'ai une variable de réponse et une donnée contenant trois covariables (à titre d'exemple jouet):

y = c(1,4,6)
d = data.frame(x1 = c(4,-1,3), x2 = c(3,9,8), x3 = c(4,-4,-2))

Je veux adapter une régression linéaire aux données:

fit = lm(y ~ d$x1 + d$x2 + d$y2)

Y a-t-il un moyen d'écrire la formule, de sorte que je n'ai pas à écrire chaque covariable? Par exemple, quelque chose comme

fit = lm(y ~ d)

(Je veux que chaque variable du bloc de données soit une covariable.) Je pose la question parce que j'ai en réalité 50 variables dans mon bloc de données. Par conséquent, je veux éviter d'écrire x1 + x2 + x3 + etc.

106
grautur

Il y a un identifiant spécial que l'on peut utiliser dans une formule pour désigner toutes les variables, il s'agit de l'identifiant ..

y <- c(1,4,6)
d <- data.frame(y = y, x1 = c(4,-1,3), x2 = c(3,9,8), x3 = c(4,-4,-2))
mod <- lm(y ~ ., data = d)

Vous pouvez aussi faire des choses comme ça, utiliser toutes les variables sauf une:

mod <- lm(y ~ . - x3, data = d)

Techniquement, . signifie toutes les variables pas déjà mentionné dans la formule. Par exemple

lm(y ~ x1 * x2 + ., data = d)

. ne ferait que référencer x3 en tant que x1 et x2 sont déjà dans la formule.

167
Gavin Simpson

Une approche légèrement différente consiste à créer votre formule à partir d'une chaîne. Dans la page d'aide formula, vous trouverez l'exemple suivant:

## Create a formula for a model with a large number of variables:
xnam <- paste("x", 1:25, sep="")
fmla <- as.formula(paste("y ~ ", paste(xnam, collapse= "+")))

Ensuite, si vous regardez la formule générée, vous obtiendrez:

R> fmla
y ~ x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + 
    x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + 
    x22 + x23 + x24 + x25
57
juba

Oui, bien sûr, ajoutez simplement la réponse y en tant que première colonne du cadre de données et appelez lm():

d2<-data.frame(y,d)
> d2
  y x1 x2 x3
1 1  4  3  4
2 4 -1  9 -4
3 6  3  8 -2
> lm(d2)

Call:
lm(formula = d2)

Coefficients:
(Intercept)           x1           x2           x3  
    -5.6316       0.7895       1.1579           NA  

De plus, mes informations sur R indiquent que l'affectation avec <- est recommandée par rapport à =.

7
Bernd Elkemann

Une extension de la méthode de juba consiste à utiliser reformulate, une fonction explicitement conçue pour une telle tâche.

## Create a formula for a model with a large number of variables:
xnam <- paste("x", 1:25, sep="")

reformulate(xnam, "y")
y ~ x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + 
    x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + 
    x22 + x23 + x24 + x25

Pour l'exemple du PO, la solution la plus simple serait ici:

# add y variable to data.frame d
d <- cbind(y, d)
reformulate(names(d)[-1], names(d[1]))
y ~ x1 + x2 + x3

ou 

mod <- lm(reformulate(names(d)[-1], names(d[1])), data=d)

Notez que l'ajout de la variable dépendante à data.frame dans d <- cbind(y, d) est préférable, non seulement parce qu'il permet l'utilisation de reformulate, mais également parce qu'il permet une utilisation future de l'objet lm dans des fonctions comme predict.

3
lmo

Je construis cette solution, reformulate ne prend pas soin si les noms de variables ont des espaces blancs.

add_backticks = function(x) {
    paste0("`", x, "`")
}

x_lm_formula = function(x) {
    paste(add_backticks(x), collapse = " + ")
}

build_lm_formula = function(x, y){
    if (length(y)>1){
        stop("y needs to be just one variable")
    }
    as.formula(        
        paste0("`",y,"`", " ~ ", x_lm_formula(x))
    )
}

# Example
df <- data.frame(
    y = c(1,4,6), 
    x1 = c(4,-1,3), 
    x2 = c(3,9,8), 
    x3 = c(4,-4,-2)
    )

# Model Specification
columns = colnames(df)
y_cols = columns[1]
x_cols = columns[2:length(columns)]
formula = build_lm_formula(x_cols, y_cols)
formula
# output
# "`y` ~ `x1` + `x2` + `x3`"

# Run Model
lm(formula = formula, data = df)
# output
Call:
    lm(formula = formula, data = df)

Coefficients:
    (Intercept)           x1           x2           x3  
        -5.6316       0.7895       1.1579           NA  

`` `

1
Christian Torrez

Vous pouvez vérifier le package leaps et en particulier la fonction regsubsets() Fonctions pour la sélection du modèle. Comme indiqué dans la documentation:

Sélection du modèle par recherche exhaustive, avance par étape, étape par étape ou remplacement séquentiel

0
amonk