Как я могу рассчитать внутренний продукт с произвольным числом столбцов, используя ddply? - PullRequest
0 голосов
/ 19 ноября 2011

Я хочу выполнить внутреннее произведение первых D столбцов для каждой строки во фрейме данных с данным массивом, W.Я пытаюсь следующее:

W = (1,2,3);
ddply(df, .(id), transform, inner_product=c(col1, col2, col3) %*% W);

Это работает, но у меня обычно может быть произвольное количество столбцов.Могу ли я обобщить приведенное выше выражение для обработки этого случая?

Обновление:

Это обновленный пример, который запрашивается в комментариях:

libary(kernlab);
data(spam);
W = array();
W[1:3] = seq(1,3);
spamdf = head(spam);
spamdf$id = seq(1,nrow(spamdf));
df_out=ddply(spamdf, .(id), transform, inner_product=c(make, address, all) %*% W);

> W
[1] 1 2 3
> spamdf[1,]
  make address  all num3d  our over remove internet order mail receive will
1    0    0.64 0.64     0 0.32    0      0        0     0    0       0 0.64
  people report addresses free business email  you credit your font num000
1      0      0         0 0.32        0  1.29 1.93      0 0.96    0      0
  money hp hpl george num650 lab labs telnet num857 data num415 num85
1     0  0   0      0      0   0    0      0      0    0      0     0
  technology num1999 parts pm direct cs meeting original project re edu table
1          0       0     0  0      0  0       0        0       0  0   0     0
  conference charSemicolon charRoundbracket charSquarebracket charExclamation
1          0             0                0                 0           0.778
  charDollar charHash capitalAve capitalLong capitalTotal type id
1          0        0      3.756          61          278 spam  1
> df_out[1,]
  make address  all num3d  our over remove internet order mail receive will
1    0    0.64 0.64     0 0.32    0      0        0     0    0       0 0.64
  people report addresses free business email  you credit your font num000
1      0      0         0 0.32        0  1.29 1.93      0 0.96    0      0
  money hp hpl george num650 lab labs telnet num857 data num415 num85
1     0  0   0      0      0   0    0      0      0    0      0     0
  technology num1999 parts pm direct cs meeting original project re edu table
1          0       0     0  0      0  0       0        0       0  0   0     0
  conference charSemicolon charRoundbracket charSquarebracket charExclamation
1          0             0                0                 0           0.778
  charDollar charHash capitalAve capitalLong capitalTotal type id inner_product
1          0        0      3.756          61          278 spam  1           3.2

Вышеприведенный пример выполняетвнутренний продукт первых трех измерений с массивом W=(1,2,3) набора данных спама, доступным в пакете kernlab .Здесь я подробно изложил первые три измерения как c(make, address, all).Таким образом, df_out[1,"inner_product"] = 3.2.

Вместо этого я хочу выполнить внутреннее произведение по всем измерениям без необходимости перечисления всех измерений.Преобразование в матрицу и обратно во фрейм данных кажется дорогой операцией?

Ответы [ 2 ]

3 голосов
/ 19 ноября 2011

Должна работать стратегия в соответствии со следующими принципами:

  • Преобразование каждого куска в матрицу
  • Выполнение умножения матрицы
  • Преобразование результатов в данные.кадр

Код:

set.seed(1)
df <- data.frame(
    id=sample(1:5, 20, replace=TRUE),
    col1 = runif(20),
    col2 = runif(20),
    col3 = runif(20),
    col4 = runif(20)
    )

W <- c(1,2,3,4)
ddply(df, .(id), function(x)as.data.frame(as.matrix(x[, -1]) %*% W))

Результаты:

   id       V1
1   1 4.924994
2   1 5.076043
3   2 7.053864
4   2 5.237132
5   2 6.307620
6   2 3.413056
7   2 5.182214
8   2 7.623164
9   3 5.194714
10  3 6.733229
11  4 4.122548
12  4 3.569013
13  4 4.978939
14  4 5.513444
15  4 5.840900
16  4 6.526522
17  5 3.530220
18  5 3.549646
19  5 4.340173
20  5 3.955517
0 голосов
/ 19 ноября 2011

Если вы хотите добавить столбец перекрестных продуктов, вы можете сделать это (при условии, что у W было правильное количество элементов, соответствующее столбцам без идентификатора:

df2 <- cbind(df, as.matrix(df[, -grep("id", names(df))]) %*% W )

Это неПохоже, что. (id) служит какой-либо полезной цели, так как вы не делаете сумму перекрестных продуктов внутри id, и если бы вы были так, вы бы не использовали преобразование, а какую-то другую агрегирующую функцию.

...