157 votes

Comment écrire succinctement une formule avec de nombreuses variables à partir d'une base de données ?

Supposons que je dispose d'une variable de réponse et de données contenant trois covariables (à titre d'exemple) :

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

Je souhaite appliquer une régression linéaire aux données :

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

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

fit = lm(y ~ d)

(Je veux que chaque variable de la base de données soit une covariable.) Je pose la question parce que j'ai en fait 50 variables dans ma base de données, et je veux donc éviter d'écrire x1 + x2 + x3 + etc .

256voto

Gavin Simpson Points 72349

Il existe un identifiant spécial que l'on peut utiliser dans une formule pour désigner toutes les variables, il s'agit de l'identifiant . 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 également faire des choses comme ceci, pour utiliser toutes les variables sauf une (dans ce cas, x3 est exclu) :

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

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

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

. ne ferait référence qu'à x3 comme x1 y x2 sont déjà dans la formule.

76voto

juba Points 15701

Une approche légèrement différente consiste à créer votre formule à partir d'une chaîne de caractères. Dans le fichier 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= "+")))

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

11voto

eznme Points 13158

Oui, bien sûr, il suffit d'ajouter la réponse y comme première colonne de l'image de données et appeler lm() sur celui-ci :

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  

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

10voto

lmo Points 31046

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 cité dans l'OP, la solution la plus simple serait la suivante

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

o

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

Notez que l'ajout de la variable dépendante au data.frame en d <- cbind(y, d) est préférée non seulement parce qu'elle permet l'utilisation de reformulate mais aussi parce qu'il permet l'utilisation future de la lm dans des fonctions telles que predict .

2voto

Je construis cette solution, reformulate ne tient pas compte des espaces blancs dans les noms de variables.

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  

```

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X