Bagaimana cara singkat menulis rumus dengan banyak variabel dari bingkai data?


127

Misalkan saya memiliki variabel respons dan data yang berisi tiga kovariat (sebagai contoh mainan):

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

Saya ingin menyesuaikan regresi linier dengan data:

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

Adakah cara untuk menuliskan rumusnya, sehingga saya tidak perlu menuliskan setiap kovariat? Misalnya, seperti

fit = lm(y ~ d)

(Saya ingin setiap variabel dalam bingkai data menjadi kovariat.) Saya bertanya karena saya sebenarnya memiliki 50 variabel dalam bingkai data saya, jadi saya ingin menghindari penulisan x1 + x2 + x3 + etc.



Jawaban:


202

Ada pengenal khusus yang dapat digunakan seseorang dalam rumus yang berarti semua variabel, itu adalah .pengenal.

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)

Anda juga dapat melakukan hal-hal seperti ini, untuk menggunakan semua variabel kecuali satu (dalam hal ini x3 dikecualikan):

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

Secara teknis, .berarti semua variabel belum disebutkan dalam rumus . Sebagai contoh

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

di mana .hanya akan mereferensikan x3sebagai x1dan x2sudah ada dalam rumus.


Data frame 'd' memiliki 4 kolom (y, x1, x2, dan x3). Jadi jika rumusnya adalah "y ~", apakah sisi kanan berarti "semua kolom" kecuali yang tercantum di sisi kiri?
stackoverflowuser2010

1
@ stackoverflowuser2010 Ya, secara .teknis berarti semua variabel data belum ada dalam rumus .
Gavin Simpson

1
@theforestecologist jika yang Anda maksud dataadalah daftar variabel dalam rumus yang dicari dari daftar itu, maka ya. Bingkai data, daftar, atau lingkungan adalah opsi yang dapat diterima untuk dataargumen tersebut. Jika bukan itu yang Anda maksud, Anda perlu mengembangkan lebih banyak.
Gavin Simpson

@Bayu_joo Itu yang saya maksud. Terima kasih. Bagaimana saya akan menggunakan metode ini menggunakan data [[x]] sebagai variabel terdaftar vs. nama variabel sebenarnya (misalnya, 'x3')? Misalnya, bagaimana saya membuat pekerjaan berikut ?:lm(d[[1]] ~ d[[3]] + ., data = d)
theforestecologist

Ia bekerja di luar namesdaftar; mengatakan Anda memiliki ll <- list(y = rnorm(10), x = rnorm(10), z = rnorm(10), zz = runif(10)), maka karya-karya berikut: lm(y ~ x + ., data = ll). Jadi tidak banyak alasan untuk memiliki data Anda seperti ini kecuali sudah ada daftar, tetapi berfungsi. Persyaratan bahwa elemen rumus memiliki panjang yang sama menempatkan beberapa batasan pada apa yang Anda miliki dalam daftar. Objek yang lebih kompleks mungkin membutuhkan kode untuk mengekstrak elemen yang Anda inginkan; jika d[[1]]kerangka data / matriks Anda memerlukan kode untuk membuatnya berfungsi
Gavin Simpson

66

Pendekatan yang sedikit berbeda adalah membuat rumus Anda dari string. Di formulahalaman bantuan Anda akan menemukan contoh berikut:

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

Kemudian jika Anda melihat rumus yang dihasilkan, Anda akan mendapatkan:

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

1
Ini bekerja sangat baik untuk membaca nilai-nilai ini dari file. Terima kasih!
Ben Sidhom

Perhatikan bahwa bagian as.formula adalah suatu keharusan
Jinhua Wang

7

Ya tentu saja, cukup tambahkan respons ysebagai kolom pertama di dataframe dan panggil 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  

Juga, informasi saya tentang R menunjukkan bahwa penugasan dengan <-direkomendasikan =.


Terima kasih! Ya, saya tahu semua orang selalu mengatakan untuk menggunakan <-, tetapi tidak ada yang pernah mengatakan mengapa dan = lebih mudah untuk mengetik =).
grautur

2
@gratur Salah satu alasannya adalah hal-hal seperti foo(bar <- 1:10)pekerjaan (dan bardibuat) tetapi foo(bar = 1:10)akan gagal karena barbukan merupakan argumen foodan tidak akan membuat barjuga.
Gavin Simpson

2
Mengapa koefisien x3 NA?
ziyuang

6

Perpanjangan metode juba adalah menggunakan reformulate, fungsi yang secara eksplisit dirancang untuk tugas semacam itu.

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

Untuk contoh di OP, solusi termudah di sini adalah

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

atau

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

Perhatikan bahwa menambahkan variabel dependen ke data.frame di d <- cbind(y, d)lebih disukai tidak hanya karena memungkinkan untuk digunakan reformulate, tetapi juga karena memungkinkan penggunaan lmobjek di masa mendatang dalam fungsi seperti predict.


2

Saya membangun solusi ini, reformulatetidak peduli jika nama variabel memiliki spasi kosong.

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  

``


0

Anda dapat memeriksa paket leapsdan khususnya fungsi regsubsets() fungsi untuk pemilihan model. Seperti yang tertera dalam dokumentasi:

Pemilihan model dengan pencarian lengkap, maju atau mundur bertahap, atau penggantian berurutan

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.