我想将数据打包到相同大小的容器中,其中每个容器是此容器中所有容器值的平均值。这很简单,一维数据分类到k=10
箱中:
library(magrittr)
sample(1000) %>% sort %>% tapply(cut(., 10), mean)
如果我有二维数据怎么办,即每个bin都包含来自二维x
和y
值的二维空间的值。那3D怎么样?你能提出一个通用的方法吗?
为简单起见,我们假设一个带有两个变量的2D数据,这两个变量的级别在此处letters
和numbers
。汇总时,此数据只有十个值,如下图所示:
1 2 3 4 5
a x . . x .
b . x . . .
c . x x x .
d . x x . x
e x . . . .
所以x
每个k
观察的平均值为[a, 1]
,k
我们a
1
和(mean(a), mean(1))
都有hexbin
个值并且值是平均值,因此它是元组{{1}}。
再举一个例子:我希望得到一个类似于{{1}}图的矩阵作为输出,但是用平均值而不是在单元格中计算。
答案 0 :(得分:1)
源是一些维度的数组,这意味着我们每个单元都有一个数据;这还没有在稀疏矩阵上进行过测试,但我不明白为什么它在理论上不起作用;以及
当你说相同大小的箱子时,我假设当原始矩阵的尺寸不均匀分开时你会接受“近似”。
这种实现的一些好处,可能是模糊不清或难以阅读:
我认为它适用于源数组的任意维度;虽然我已经对某些案例进行了测试,但我并不是百分之百地确信它是万无一失的;以及
它将允许任意汇总函数,默认为mean
;这可能在减少矩阵但仍然需要其集中趋势(例如mean
,median
)和分散(例如sd
,var
,{{ 1}},range
)。显然,这里可以使用任意数量的函数,只要它们接受第一个参数为任意维度的数组而不是其他。
IQR
reduceMatrix <- function(x, newdim, func = mean) {
if (length(newdim) == 1)
newdim <- rep(newdim, length(dim(x)))
if (length(dim(x)) != length(newdim))
stop('newdim must be of length 1 or the same length as dimensions of x')
allCuts <- lapply(1:length(newdim), function(d) {
tmp <- round(sapply(dim(x)[d], function(y) seq(1, 1 + y, len = 1 + newdim[d])),
digits = 0)
mapply(seq, head(tmp, n = -1), tmp[-1] - 1, SIMPLIFY = FALSE)
})
newIndices <- lapply(newdim, function(d) seq(1, d))
eg <- do.call(expand.grid, newIndices)
f <- function(m, cuts, ...) func(do.call(`[`, c(list(m), mapply(`[`, cuts, list(...)))))
ret <- do.call(mapply, c(list(FUN=f), list(list(x)), list(list(allCuts)), eg))
array(ret, dim = newdim)
}
dim2 <- c(8,8)
mtx2 <- array(1:prod(dim2), dim = dim2)
mtx2
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
## [1,] 1 9 17 25 33 41 49 57
## [2,] 2 10 18 26 34 42 50 58
## [3,] 3 11 19 27 35 43 51 59
## [4,] 4 12 20 28 36 44 52 60
## [5,] 5 13 21 29 37 45 53 61
## [6,] 6 14 22 30 38 46 54 62
## [7,] 7 15 23 31 39 47 55 63
## [8,] 8 16 24 32 40 48 56 64
reduceMatrix(mtx2, newdim = 2)
## [,1] [,2]
## [1,] 14.5 46.5
## [2,] 18.5 50.5
matrix(c(mean(mtx2[1:4,1:4]), mean(mtx2[1:4,5:8]),
mean(mtx2[5:8,1:4]), mean(mtx2[5:8,5:8])),
nrow = 2, byrow = TRUE)
## [,1] [,2]
## [1,] 14.5 46.5
## [2,] 18.5 50.5
这甚至可以减小从3D到2D的深度(在这种情况下):
dim3 <- c(4,4,16)
mtx3 <- array(1:prod(dim3), dim = dim3)
mtx3[,,1:2]
## , , 1
## [,1] [,2] [,3] [,4]
## [1,] 1 5 9 13
## [2,] 2 6 10 14
## [3,] 3 7 11 15
## [4,] 4 8 12 16
## , , 2
## [,1] [,2] [,3] [,4]
## [1,] 17 21 25 29
## [2,] 18 22 26 30
## [3,] 19 23 27 31
## [4,] 20 24 28 32
reduceMatrix(mtx3, newdim = c(2, 4, 2))
## , , 1
## [,1] [,2] [,3] [,4]
## [1,] 57.5 61.5 65.5 69.5
## [2,] 59.5 63.5 67.5 71.5
## , , 2
## [,1] [,2] [,3] [,4]
## [1,] 185.5 189.5 193.5 197.5
## [2,] 187.5 191.5 195.5 199.5
mean(mtx3[1:2, 4, 1:8])
## [1] 69.5
reduceMatrix(mtx3, newdim = c(2, 4, 1))
## , , 1
## [,1] [,2] [,3] [,4]
## [1,] 121.5 125.5 129.5 133.5
## [2,] 123.5 127.5 131.5 135.5
在这种情况下,鉴于数据的连续性,reduceMatrix(mtx3, newdim = c(2, 4, 1), func = min)
## , , 1
## [,1] [,2] [,3] [,4]
## [1,] 1 5 9 13
## [2,] 3 7 11 15
reduceMatrix(mtx3, newdim = c(2, 4, 1), func = sd)
## , , 1
## [,1] [,2] [,3] [,4]
## [1,] 74.93825 74.93825 74.93825 74.93825
## [2,] 74.93825 74.93825 74.93825 74.93825
的结果并不令人惊讶......
sd
(我意识到第17次重新阅读你的问题陈述,你的输出不是我想象的。我想知道这是否可以改编......)
答案 1 :(得分:0)
嗯...好像你想要排序等级的互斥集群。
我确信它可以用于2D&amp; 3D,但我不确定解决方案是否必然是唯一的,除非变量有层次结构。
作为唯一性问题的一个例子,考虑一个二维空间,其中均匀分布的数据以原点为中心,k = 2.任何一对线将数据平均分成4个区(即通过原点的任意两条线)正交)将创建一个4 bin的情况,但除非我们对这两个变量中的每一个都有一些加权,否则排序很难定义。
但是,如果您具有每个变量的相对权重(或重要性)......可以使用2D空间到1D空间的任何投影来定义等级,并且可以定义最佳解决方案。