Умножение двух наборов векторов в R


Предположим, что у меня есть две матрицы A и B:

 A:      A1    A2        B:      B1   B2
   ROW1  V1    V2          ROW1  V3   V4
   ROW2  V5    V6          ROW2  V7   V8

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

 R:      A1_B1  A1_B2  A2_B1  A2_B2
   ROW1  V1*V3  V1*V4  V2*V3  V2*V4
   ROW2  V5*V7  V5*V8  V6*V7  V6*V8

Петлевая структура может подойти,но мне интересно, есть ли лучшие варианты.

3 3

3 ответа:

Вы можете использовать apply:

A <- matrix(1:4,2,2)
#     [,1] [,2]
# [1,]    1    3
# [2,]    2    4
B <- A * 10
#      [,1] [,2]
# [1,]   10   30
# [2,]   20   40

matrix(apply(A, 2, "*", B), nrow = nrow(A))
#      [,1] [,2] [,3] [,4]
# [1,]   10   30   30   90
# [2,]   40   80   80  160

добавление Антти:

Это прекрасно работает. В конце концов, я нуждался в этом для манипулирования a data.frame. Чтобы применить значимые имена столбцов для этого data.frame, я сделал следующее:

  1. Сделайте эту матрицу данными.кадр:

    R <- as.data.frame(R)
    
  2. Сделать векторы имен столбцов в A и B

    Acol <- grep("A", names(data.frame(A)), value = T) 
    Bcol <- grep("B", names(data.frame(B)), value = T) 
    
  3. Затем переименуйте столбцы R:

    colnames(R) <- outer(Acol, Bcol, paste, sep = ".")
    

Сначала давайте сделаем некоторые реальные данные, с которыми мы действительно можем работать:

> A=matrix(c(1,5,2,6),2,2)
> B=matrix(c(3,7,4,8),2,2)
> A
     [,1] [,2]
[1,]    1    2
[2,]    5    6
> B
     [,1] [,2]
[1,]    3    4
[2,]    7    8
Теперь задача состоит в простом умножении комбинаций правых столбцов из A и B. эти комбинации равны A1, A1, A2, A2 раз (соответственно) B1 B2 B1 B2 - и мы можем получить эти комбинации из expand.grid:
> cols = as.matrix(expand.grid(1:2,1:2))
> cols
     Var1 Var2
[1,]    1    1
[2,]    2    1
[3,]    1    2
[4,]    2    2

Тогда мы получим столбцы этого как столбцы A и B (в другом порядке):

> A[,cols[,2]] * B[,cols[,1]]
     [,1] [,2] [,3] [,4]
[1,]    3    4    6    8
[2,]   35   40   42   48

QED

[Обратите внимание, как я тщательно построил A и B, чтобы соответствовать вашим V-номерам, так что вы можете видеть что там, где у вас есть V6*V8, у меня есть 6 * 8]

A <- matrix(1:4,2,2)
B <- A * 10

cbind(A[,1]*B, A[,2]*B)

     [,1] [,2] [,3] [,4]
[1,]   10   30   30   90
[2,]   40   80   80  160