2010-01-17 3 views
14

Есть ли способ - кроме цикла for - генерировать новые переменные в R-кадре R, что будет всеми возможными двухсторонними взаимодействиями между существующими? т.е. допуская dataframe с тремя числовых переменных V1, V2, V3, Я хотел бы генерировать следующие новые переменные:Создание переменных взаимодействия в R-кадрах данных

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

Пример используя для цикла:

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

     } 
} 

ответ

27

Вот один вкладыш для Вас, который также работает, если у вас есть факторы:

> 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 Не знал о функции model.matrix. Очень полезно! – Shane

+2

Отлично! Вы также можете избавиться от нерелевантного (в нашем случае) перехвата model.matrix (~ (V1 + V2 + V3 + V4)^2-1, x) –

+2

Вы правы. или для полностью общего случая as.data.frame (model.matrix (~.^2-1, x)) –

10

Здесь вы идете, используя combn и apply:

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

Настройка имен столбцов можно сделать с помощью двух paste команд:

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

Наконец, если вы хотите, чтобы все переменные вместе, просто cbind их:

> 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

Очень приятно! Есть ли способ изменить имена столбцов, в соответствии с примером, используя apply? –

+0

Я обновил его, чтобы показать это. – Shane

+1

Если вы собираетесь использовать эти взаимодействия в моделях, которые принимают формулу, например, lm или glm, вам не нужно генерировать переменные. Смотрите: http://cran.r-project.org/doc/manuals/R-intro.html#Formulae-for-statistical-models – Tristan

0

Я думаю, этот вопрос должен быть дополнен функцией poly/polym, которая идет дальше: она генерирует не только взаимодействия между переменными, но и мощность до выбранной степени. И orthogonal iteractions, что может быть очень полезно.

Непосредственно решение проблемы просил бы:

> 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 

В столбцах 4, 7, 8, 11, 12, 13 имеет запрашиваемые в вопросе. Другие столбцы имеют другие виды взаимодействий. Если вы хотите получить ортогональные взаимодействия, просто установите raw = FALSE.

Смежные вопросы