2017-08-22 19 views
3

私は3つのデータセットを持っています。ある列の各観測については、他のデータセットの対応する列のすべての観測値を乗算したいと考えています。以下の例はうまく説明するでしょう。実際のデータは約200行あります。これはすべて可能ですか?ループを使用する必要がありますか?私は、より多くのデータセットを含めるためにこれをスケールアップしたいと思っています。別のデータフレームで観測ごとに掛け合わせる

Data set 1 
     [A] [B] [C] 
    [1] A1 B1 C1 
    [2] A2 B2 C2 
    [3] A3 B3 C3 

    Data set 2 
     [L] [M] [N] 
    [1] L1 M1 N1 
    [2] L2 M2 N2 
    [3] L3 M3 N3 

    Data set 3 
     [X] [Y] [Z] 
    [1] X1 Y1 Z1 
    [2] X2 Y2 Z2 
    [3] X3 Y3 Z3 

    Output 
       [,1]  [,2]  [,3] 
    [1,] A1*L1*X1 B1*M1*Y1 C1*N1*Z1 
    [2,] A1*L1*X2  ...  ... 
    [3,] A1*L1*X3  ...  ... 
    [4,] A1*L2*X1  ...  ... 
    [5,] A1*L2*X2  ...  ... 
    [6,] A1*L2*X3  ...  ... 
    [7,] A1*L3*X1  ...  ... 
    [8,] A1*L3*X2  ...  ... 
    [9,] A1*L3*X3  ...  ... 
    [...] 
    [27,] A3*L3*X3  ...  ... 
+1

'?kronecker'を見てください – coffeinjunky

+0

@ zx8754 - 私は同じことを考えました。しかし、望ましい出力は27の行を示します。 – Sagar

+1

私は彼がクロネッカーの製品を望んでいると思います。それぞれの要素に他の行列の各要素を乗じたものです。これは 'kronecker(matA、kronecker(matB、matC))'のようなものです。 – coffeinjunky

答えて

2

以下は、お好みに合っていますか?

A <- data.frame(matrix(1:6, ncol = 2) 
B <- matrix(1:6, ncol = 2) 
C <- matrix(1:6, ncol = 2) 

out <- data.frame(mapply(kronecker, A, B)) 
out2 <- mapply(kronecker, out, C) 
out2 
     X1 X2 
[1,] 1 64 
[2,] 2 80 
[3,] 3 96 
[4,] 2 80 
[5,] 4 100 
[6,] 6 120 
[7,] 3 96 
[8,] 6 120 
[9,] 9 144 
[10,] 2 80 
[11,] 4 100 
[12,] 6 120 
[13,] 4 100 
[14,] 8 125 
[15,] 12 150 
[16,] 6 120 
[17,] 12 150 
[18,] 18 180 
[19,] 3 96 
[20,] 6 120 
[21,] 9 144 
[22,] 6 120 
[23,] 12 150 
[24,] 18 180 
[25,] 9 144 
[26,] 18 180 
[27,] 27 216 

そして、それを一般化するには、インスタンスのために使用することができます

hlpfun <- function(one, two) { 
    data.frame(mapply(kronecker, one, two)) 
} 

Reduce(hlpfun,list(A,B,C)) 

を(クレジットはウェンさんのコメント@に行く)

ここで私は彼を変換猿の行列@使用してテストケース、行列はdata.framesになり、FUN = pastekronekerとなります(実際に数値を乗算したい場合はこれをしないでください)。

hlpfun <- function(one, two) { 
    data.frame(mapply(kronecker, one, two, MoreArgs = list(FUN = paste))) 
} 
Reduce(hlpfun,list(data.frame(mat1),data.frame(mat2),data.frame(mat3))) 
     X1  X2  X3 
1 A1 L1 X1 B1 M1 Y1 C1 N1 Z1 
2 A1 L1 X2 B1 M1 Y2 C1 N1 Z2 
3 A1 L1 X3 B1 M1 Y3 C1 N1 Z3 
4 A1 L2 X1 B1 M2 Y1 C1 N2 Z1 
5 A1 L2 X2 B1 M2 Y2 C1 N2 Z2 
6 A1 L2 X3 B1 M2 Y3 C1 N2 Z3 
7 A1 L3 X1 B1 M3 Y1 C1 N3 Z1 
8 A1 L3 X2 B1 M3 Y2 C1 N3 Z2 
9 A1 L3 X3 B1 M3 Y3 C1 N3 Z3 
10 A2 L1 X1 B2 M1 Y1 C2 N1 Z1 
11 A2 L1 X2 B2 M1 Y2 C2 N1 Z2 
12 A2 L1 X3 B2 M1 Y3 C2 N1 Z3 
13 A2 L2 X1 B2 M2 Y1 C2 N2 Z1 
14 A2 L2 X2 B2 M2 Y2 C2 N2 Z2 
15 A2 L2 X3 B2 M2 Y3 C2 N2 Z3 
16 A2 L3 X1 B2 M3 Y1 C2 N3 Z1 
17 A2 L3 X2 B2 M3 Y2 C2 N3 Z2 
18 A2 L3 X3 B2 M3 Y3 C2 N3 Z3 
19 A3 L1 X1 B3 M1 Y1 C3 N1 Z1 
20 A3 L1 X2 B3 M1 Y2 C3 N1 Z2 
21 A3 L1 X3 B3 M1 Y3 C3 N1 Z3 
22 A3 L2 X1 B3 M2 Y1 C3 N2 Z1 
23 A3 L2 X2 B3 M2 Y2 C3 N2 Z2 
24 A3 L2 X3 B3 M2 Y3 C3 N2 Z3 
25 A3 L3 X1 B3 M3 Y1 C3 N3 Z1 
26 A3 L3 X2 B3 M3 Y2 C3 N3 Z2 
27 A3 L3 X3 B3 M3 Y3 C3 N3 Z3 

小さな説明を追加すると、mapplyは2つの引数を同時に通過して関数を適用します。 data.framesは、各列がリスト内の要素であるため、data.framesmapplyの2つを入力することで、最初の列に、次に2番目の列に、次に3番目に... data.framesに入力する関数を適用します。これを使用して列方向のkronecker製品を得ることができます。

2

1つのオプションは、各データフレームの行を適切なパターンで複製し、それらを一緒に掛けることです。

データ:

(A <- matrix(1:6, 3)) 
#  [,1] [,2] 
# [1,] 1 4 
# [2,] 2 5 
# [3,] 3 6 
(B <- matrix(2:5, 2)) 
#  [,1] [,2] 
# [1,] 2 4 
# [2,] 3 5 
(C <- matrix(3:8, 3)) 
#  [,1] [,2] 
# [1,] 3 6 
# [2,] 4 7 
# [3,] 5 8 

Aの各行は、Bのすべての行のための十分な時間を複製しなければならないが、Cのすべての行とペア:Bの

A[rep(seq_len(nrow(A)), each=nrow(B)*nrow(C)),] 
#  [,1] [,2] 
# [1,] 1 4 
# [2,] 1 4 
# [3,] 1 4 
# [4,] 1 4 
# [5,] 1 4 
# [6,] 1 4 
# [7,] 2 5 
# [8,] 2 5 
# [9,] 2 5 
# [10,] 2 5 
# [11,] 2 5 
# [12,] 2 5 
# [13,] 3 6 
# [14,] 3 6 
# [15,] 3 6 
# [16,] 3 6 
# [17,] 3 6 
# [18,] 3 6 

行はすべてのために複製される必要がありますこのパターンはAのすべての行に対して再度コピーする必要があります。

B[rep(rep(seq_len(nrow(B)), each=nrow(C)), nrow(A)),] 
#  [,1] [,2] 
# [1,] 2 4 
# [2,] 2 4 
# [3,] 2 4 
# [4,] 3 5 
# [5,] 3 5 
# [6,] 3 5 
# [7,] 2 4 
# [8,] 2 4 
# [9,] 2 4 
# [10,] 3 5 
# [11,] 3 5 
# [12,] 3 5 
# [13,] 2 4 
# [14,] 2 4 
# [15,] 2 4 
# [16,] 3 5 
# [17,] 3 5 
# [18,] 3 5 

BのすべてのAの行と行のために一度繰り返されるように:これも困難に多くのkroneckerのようなものよりもタイピングとは

A[rep(seq_len(nrow(A)), each=nrow(B)*nrow(C)),] * 
    B[rep(rep(seq_len(nrow(B)), each=nrow(C)), nrow(A)),] * 
    C[rep(seq_len(nrow(C)), nrow(A)*nrow(B)),] 
#  [,1] [,2] 
# [1,] 6 96 
# [2,] 8 112 
# [3,] 10 128 
# [4,] 9 120 
# [5,] 12 140 
# [6,] 15 160 
# [7,] 12 120 
# [8,] 16 140 
# [9,] 20 160 
# [10,] 18 150 
# [11,] 24 175 
# [12,] 30 200 
# [13,] 18 144 
# [14,] 24 168 
# [15,] 30 192 
# [16,] 27 180 
# [17,] 36 210 
# [18,] 45 240 

C[rep(seq_len(nrow(C)), nrow(A)*nrow(B)),] 
#  [,1] [,2] 
# [1,] 3 6 
# [2,] 4 7 
# [3,] 5 8 
# [4,] 3 6 
# [5,] 4 7 
# [6,] 5 8 
# [7,] 3 6 
# [8,] 4 7 
# [9,] 5 8 
# [10,] 3 6 
# [11,] 4 7 
# [12,] 5 8 
# [13,] 3 6 
# [14,] 4 7 
# [15,] 5 8 
# [16,] 3 6 
# [17,] 4 7 
# [18,] 5 8 

一緒にこれらの3を乗算結果をもたらしより多くの行列に拡張されましたが、私はオプションとして投稿したかったのです。なぜなら、repと行列行インデックスを使用するだけなので、何が起こっているのかを簡単に確認できます。また、列を返すMatrixパッケージ内の関数があります:

1
# data 
mat1 <- matrix(paste0(rep(c("A","B","C"), each = 3), rep(1:3, times = 3)), ncol = 3) 
mat2 <- matrix(paste0(rep(c("L","M","N"), each = 3), rep(1:3, times = 3)), ncol = 3) 
mat3 <- matrix(paste0(rep(c("X","Y","Z"), each = 3), rep(1:3, times = 3)), ncol = 3) 

sapply(1:3, function(k){outer(outer(mat3[,k], mat2[,k], FUN = "paste"), 
    mat1[,k], FUN = "paste")}) 

sapply

# not reproducible 
sapply(1:3, function(k){outer(outer(num_mat3[,k], num_mat2[,k], FUN = "*"), 
    num_mat1[,k], FUN = "*")}) 

"*"と編集にpasteを置き換え、数値行列 'を掛ける' に

 [,1]  [,2]  [,3]  
[1,] "X1 L1 A1" "Y1 M1 B1" "Z1 N1 C1" 
[2,] "X2 L1 A1" "Y2 M1 B1" "Z2 N1 C1" 
[3,] "X3 L1 A1" "Y3 M1 B1" "Z3 N1 C1" 
[4,] "X1 L2 A1" "Y1 M2 B1" "Z1 N2 C1" 
.... 
[27,] "X3 L3 A3" "Y3 M3 B3" "Z3 N3 C3" 

を与えますKronecker(Khatri-Rao)製品:

library(Matrix) 
KhatriRao(KhatriRao(num_mat1, num_mat2), num_mat3) 
関連する問題