Jak zwięźle napisać formułę z wieloma zmiennymi z ramki danych?

Załóżmy, że mam zmienną odpowiedzi i dane zawierające trzy kowarianty (jako przykład zabawkowy):

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

Chcę dopasować regresję liniową do danych:

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

Czy istnieje sposób, aby napisać formułę, tak, że nie muszę wypisywać poszczególnych kowariantnych? Na przykład coś w rodzaju

fit = lm(y ~ d)

(chcę, aby każda zmienna w ramce danych była kowariantną.) Pytam, bo w ramce danych Mam 50 zmiennych, więc chcę uniknąć wypisywania x1 + x2 + x3 + etc.

Author: zx8754, 2011-03-09

6 answers

Istnieje specjalny identyfikator, którego można użyć w formule, aby oznaczać wszystkie zmienne, Jest to identyfikator ..

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)

Możesz również zrobić takie rzeczy, aby użyć wszystkich zmiennych paska pierwszego:

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

Technicznie, . oznacza wszystkie zmienne Nie wymienione już we wzorze. Na przykład

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

Gdzie . oznaczałoby tylko x3 jako x1 i x2 są już we wzorze.

 161
Author: Gavin Simpson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-03 14:54:04

Nieco innym podejściem jest tworzenie formuły z ciągu. Na stronie pomocy formula znajdziesz następujący przykład:

## 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= "+")))

Wtedy jeśli spojrzysz na wygenerowaną formułę, otrzymasz:

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
 55
Author: juba,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-09 22:20:40

Tak oczywiście, wystarczy dodać odpowiedź y jako pierwszą kolumnę w ramce danych i wywołać lm() na niej:

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  

Również moje informacje o R wskazują, że przypisanie z {[3] } jest zalecane nad =.

 7
Author: Bernd Elkemann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-09 20:11:46

Rozszerzeniem metody juba jest użycie reformulate, funkcji, która jest jawnie zaprojektowana do takiego zadania.

## 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

Dla przykładu w OP najprostszym rozwiązaniem byłoby

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

Lub

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

Zauważ, że dodanie zmiennej zależnej do danych.ramka w {[4] } jest preferowana nie tylko dlatego, że pozwala na użycie reformulate, ale także dlatego, że pozwala na przyszłe użycie obiektu lm w funkcjach takich jak predict.

 2
Author: lmo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-04 15:49:16

Buduję To rozwiązanie, reformulate nie dba o to, czy nazwy zmiennych mają białe spacje.

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
Author: Christian Torrez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-15 01:12:05

Możesz sprawdzić pakiet leaps, a w szczególności funkcję regsubsets() funkcje do wyboru modelu. Jak podano w dokumentacji:

Wybór modelu poprzez wyczerpujące wyszukiwanie, krok do przodu lub do tyłu lub sekwencyjną wymianę

 0
Author: amonk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-03 10:02:51