我正在尝试以有效的方式基于维名称聚合数组。
ex_array <- array(1:10000, dim = c(100, 10, 10),
dimnames = list(Col1 = c(rep(10,50), rep(20, 50)),
Col2 = 1:10,
Col3 = 1:10))
现在我想根据第一个维度的名称聚合这个数组。此维度有2个不同的名称(10和20),因此新数组的维度应为2乘10乘10.所有维度名称1等于10的值应相加,维度1等于20的值应该总结。
有没有一些聪明的方法呢?
答案 0 :(得分:2)
要仅对其中一个维度名称执行此操作,它可能只是:
apply( ex_array[dimnames(ex_array)[[1]] == "10",,], 2:3, sum)
如果您在sapply
调用中将其换行,则会获得包含正确信息的2 x prod(N1, N2)
矩阵。我使用了缩小版的示例数据集:
ex_array <- array(1:360, dim = c(10, 6, 6),
dimnames = list(Col1 = c(rep(10,5), rep(20,5 )),
Col2 = 1:6,
Col3 = 1:6))
str( sapply(unique(dimnames(ex_array)[[1]]), function(x) apply( ex_array[dimnames(ex_array)[[1]] == x,,], 2:3, sum)) )
int [1:36, 1:2] 15 65 115 165 215 265 315 365 415 465 ...
- attr(*, "dimnames")=List of 2
..$ : NULL
..$ : chr [1:2] "10" "20"
....但它按照列主要顺序并将其重新转换为2 x N1 x N2阵列,然后需要对其进行转置,因此&#34; 10&#34;值是顶行和&#34; 20&#34;值是第二行。然后,这些值可以重铸为2 x N1 xN2阵列。您可以将其视为首次放置&#34; 10&#34;在适当的切片坐标中的值,然后放置&#34; 20&#34;价值坐标,等等:
target <- array( t( # need to process the transpose
sapply(unique(dimnames(ex_array)[[1]]),
function(x) apply( ex_array[dimnames(ex_array)[[1]] == x,,], 2:3, sum))
),
dim= c( length( unique( dimnames(ex_array)[[1]])), dim(ex_array)[2:3]) )
str(target)
# int [1:2, 1:6, 1:6] 15 40 65 90 115 140 165 190 215 240 ...
然后我检查了第一个切片与我在开头时得到的单个名称结果相同:
target[1,,] == apply( ex_array[dimnames(ex_array)[[1]] == "10",,], 2:3, sum)
Col3
Col2 1 2 3 4 5 6
1 TRUE TRUE TRUE TRUE TRUE TRUE
2 TRUE TRUE TRUE TRUE TRUE TRUE
3 TRUE TRUE TRUE TRUE TRUE TRUE
4 TRUE TRUE TRUE TRUE TRUE TRUE
5 TRUE TRUE TRUE TRUE TRUE TRUE
6 TRUE TRUE TRUE TRUE TRUE TRUE
答案 1 :(得分:2)
reshape2。我认为reshape2最适合这里,如果您愿意使用套餐:
library(reshape2)
res = acast(melt(ex_array), Col1 ~ Col2 ~ Col3, fun.aggregate = sum)
str(res)
# int [1:2, 1:10, 1:10] 1275 3775 6275 8775 11275 13775 16275 18775 21275 23775 ...
# - attr(*, "dimnames")=List of 3
# ..$ : chr [1:2] "10" "20"
# ..$ : chr [1:10] "1" "2" "3" "4" ...
# ..$ : chr [1:10] "1" "2" "3" "4" ...
我认为这也会破坏其他方面的重复数据。名字(如果有的话)。
基础R。您可以使用rowsum
,但它在这里很笨拙,因为它是为矩阵设计的
res2 = array(, c(2, 10, 10), dimnames = lapply(dimnames(ex_array), unique))
res2[] = sapply(seq_len(dim(ex_array)[3]), function(k)
rowsum(ex_array[,,k], rownames(ex_array[,,k])))