2010-01-17 29 views
14

Có cách nào khác với vòng lặp for - để tạo các biến mới trong một khung dữ liệu R, đây có phải là tất cả các tương tác 2 chiều giữa các biến hiện có không? tức là giả một dataframe với ba biến số V1, V2, V3, tôi muốn tạo ra các biến mới như sau:Tạo các biến tương tác trong các khung dữ liệu R

Inter.V1V2 (= V1 * V2) 
Inter.V1V3 (= V1 * V3) 
Inter.V2V3 (= V2 * V3) 

Ví dụ sử dụng vòng lặp for:

x <- read.table(textConnection(' 
    V1 V2 V3 V4 
1 9 25 18 
2 5 20 10 
3 4 30 12 
4 4 34 16' 
), header=TRUE) 

dim.init <- dim(x)[2] 
for (i in 1: (dim.init - 1)) { 
     for (j in (i + 1) : (dim.init)) { 
       x[dim(x)[2] + 1] <- x[i] * x[j] 
       names(x)[dim(x)[2]] <- paste("Inter.V",i,"V",j,sep="") 

     } 
} 

Trả lời

27

Đây là một lót một cho bạn rằng cũng làm việc nếu bạn có các yếu tố:

> model.matrix(~(V1+V2+V3+V4)^2,x) 
    (Intercept) V1 V2 V3 V4 V1:V2 V1:V3 V1:V4 V2:V3 V2:V4 V3:V4 
1   1 1 9 25 18  9 25 18 225 162 450 
2   1 2 5 20 10 10 40 20 100 50 200 
3   1 3 4 30 12 12 90 36 120 48 360 
4   1 4 4 34 16 16 136 64 136 64 544 
attr(,"assign") 
[1] 0 1 2 3 4 5 6 7 8 9 10 
+0

+1 Không nhận thức được chức năng model.matrix. Rất hữu dụng! – Shane

+2

Tuyệt vời! Bạn cũng có thể loại bỏ trường hợp không liên quan (trong trường hợp của chúng tôi) chặn mô hình.matrix (~ (V1 + V2 + V3 + V4)^2-1, x) –

+2

đúng. hoặc cho toàn bộ trường hợp chung là .data.frame (model.matrix (~.^2-1, x)) –

10

Ở đây bạn đi, sử dụng combnapply:

> x2 <- t(apply(x, 1, combn, 2, prod)) 

Thiết lập tên cột có thể được thực hiện với hai paste lệnh:

> colnames(x2) <- paste("Inter.V", combn(1:4, 2, paste, collapse="V"), sep="") 

Cuối cùng, nếu bạn muốn tất cả các biến của bạn với nhau, chỉ cần cbind họ:

> x <- cbind(x, x2) 
> V1 V2 V3 V4 Inter.V1V2 Inter.V1V3 Inter.V1V4 Inter.V2V3 Inter.V2V4 Inter.V3V4 
1 1 9 25 18   9   25   18  225  162  450 
2 2 5 20 10   10   40   20  100   50  200 
3 3 4 30 12   12   90   36  120   48  360 
4 4 4 34 16   16  136   64  136   64  544 
+0

Rất đẹp! Có cách nào cũng thay đổi tên cột, theo ví dụ, sử dụng áp dụng? –

+0

Tôi đã cập nhật nó để hiển thị điều này. – Shane

+1

Nếu bạn chỉ sử dụng những tương tác này trong các mô hình có công thức, chẳng hạn như lm hoặc glm, bạn không cần tạo các biến. Xem: http://cran.r-project.org/doc/manuals/R-intro.html#Formulae-for-statistical-models – Tristan

0

Tôi nghĩ rằng câu hỏi này nên được bổ sung với hàm poly/polym, đi xa hơn: nó tạo ra không chỉ các tương tác giữa các biến, mà là sức mạnh của nó cho đến mức được chọn. Và orthogonal iteractions, có thể rất hữu ích.

Giải pháp trực tiếp đến vấn đề hỏi sẽ là:

> polym(x$V1, x$V2, x$V3, x$V4, degree = 2, raw = T) 
    1.0.0.0 2.0.0.0 0.1.0.0 1.1.0.0 0.2.0.0 0.0.1.0 1.0.1.0 0.1.1.0 0.0.2.0 0.0.0.1 1.0.0.1 0.1.0.1 0.0.1.1 0.0.0.2 
[1,]  1  1  9  9  81  25  25  225  625  18  18  162  450  324 
[2,]  2  4  5  10  25  20  40  100  400  10  20  50  200  100 
[3,]  3  9  4  12  16  30  90  120  900  12  36  48  360  144 
[4,]  4  16  4  16  16  34  136  136 1156  16  64  64  544  256 
attr(,"degree") 
[1] 1 2 1 2 2 1 2 2 2 1 2 2 2 2 

Các cột 4, 7, 8, 11, 12, 13 có các yêu cầu trong câu hỏi. Các cột khác có các loại tương tác khác. Nếu bạn muốn nhận các tương tác trực giao, chỉ cần đặt raw = FALSE.

Các vấn đề liên quan