bounty将在4天后过期。此问题的答案可获得+50声誉奖励。Adrian正在寻找此问题的最新答案。
我有一个矩阵,其中包含几个国家的工业经济信息。我想根据矩阵中元素的位置和相应的列/行名称进行一系列计算。
行/列名称具有三个字母的国家/地区代码,后跟行业编号。行和列名称相同。
计算如下:
1.对于行中的每个元素,都将存在匹配的国家/地区和行业
1.保持产业组合不变,在比赛中把纯粹同一个国家的产业与另一个国家的同一个产业相乘。
我将给予一个简单的例子,尽管我的数据比这个例子大得多。
假设有矩阵a
set.seed(10)
a <- matrix(sample(36) , nrow = 6)
colnames(a) <- rownames(a) <- paste( rep(c("aaa" , "bbb" , "ccc") , each = 2), rep(c(1:2) , times = 3))
给予:
aaa 1 aaa 2 bbb 1 bbb 2 ccc 1 ccc 2
aaa 1 9 19 26 6 5 21
aaa 2 10 24 2 30 36 27
bbb 1 12 15 13 11 20 16
bbb 2 8 28 33 18 34 17
ccc 1 22 35 14 23 29 4
ccc 2 7 31 25 32 1 3
在这个例子中有三个国家“aaa”,“bbb”和“ccc”而只有两个产业,1和2。我想计算在他们自己的国家生产的产业的价值,并相互相乘。
例如,在a[1, 4]
中,这将匹配“aaa 1”与“bbb 2”。我想为每个国家乘以行业组合1 - 2,即“aaa 1”-“aaa 2”与“bbb 1”-“bbb 2”(19 * 11 = 209)。沿着对角线块的值将被平方(同一国家的两倍)。
最终矩阵如下所示:
aaa 1 aaa 2 bbb 1 bbb 2 ccc 1 ccc 2
aaa 1 81 361 117 209 261 76
aaa 2 100 576 330 432 10 72
bbb 1 117 209 169 121 377 44
bbb 2 330 432 1089 324 33 54
ccc 1 261 76 377 44 841 16
ccc 2 10 72 33 54 1 9
我用下面这段低效的代码手工计算出来的:
b <- kronecker(diag(1, 3), matrix(1, 2, 2))
b <- (a * b)^2
c <- b
c[1,3] <- 9 * 13
c[1,4] <- 19 * 11
c[1,5] <- 9 * 29
c[1,6] <- 19 * 4
c[2,3] <- 10 * 33
c[2,4] <- 24 * 18
c[2,5] <- 10 * 1
c[2,6] <- 24 * 3
.
.
.
c[6,1] <- 1 * 10
c[6,2] <- 3 * 24
c[6,3] <- 1 * 33
c[6,4] <- 3 * 18
是否有一个灵活的代码来计算这一点,而不考虑数据中的国家和行业数量?我感谢任何帮助。
编辑:我正在处理的矩阵很大(维数超过2000 * 2000)。我需要一个代码来处理这类数据而不冻结R。不幸的是,outer
可以解决这里提出的较小矩阵的问题,但在处理较大矩阵时会卡住。
3条答案
按热度按时间nkhmeac61#
更新!
假设每个国家的产业数量相等,
dimnames(a)
的排序为A1,A2...Am,B1,B2,... Bm,该方法利用了向量化计算的优势,避免了用dimname索引矩阵,从而大大提高了效率并节省了内存。m
:行业数量旧版本
bzzcjhmw2#
如果实际的矩阵
a
是n
-x-n
,且n
小于10000,那么类似这样的方法应该可以很好地执行。您可以进一步优化,特别是如果您知道dimnames(a)
是排序的(例如,参见@DarrenTsai的answer),但这显然不是必要的。当然,如果
dimnames(a)
没有排序,但您希望从排序中获益,那么您可以置换a
的行和列,对得到的分块矩阵进行操作,并对答案的行和列进行逆置换。实际上,这里有一些简洁的矩阵代数,
r.pp
的块[i,j]
是[i,i]
和a.pp
的块[j,j]
的元素积,因此r.pp
可以看作是b
的一种块叉积,因为b
是a.pp
的对角块的水平连接。oxalkeyp3#
您可以尝试下面的代码