将2D数据打包到相同大小的箱中

时间:2014-12-04 13:25:32

标签: r sorting

我想将数据打包到相同大小的容器中,其中每个容器是此容器中所有容器值的平均值。这很简单,一维数据分类到k=10箱中:

library(magrittr)

sample(1000) %>% sort %>% tapply(cut(., 10), mean)

如果我有二维数据怎么办,即每个bin都包含来自二维xy值的二维空间的值。那3D怎么样?你能提出一个通用的方法吗?

为简单起见,我们假设一个带有两个变量的2D数据,这两个变量的级别在此处lettersnumbers。汇总时,此数据只有十个值,如下图所示:

  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}}图的矩阵作为输出,但是用平均值而不是在单元格中计算。

hexbin plot example

2 个答案:

答案 0 :(得分:1)

假设

  • 源是一些维度的数组,这意味着我们每个单元都有一个数据;这还没有在稀疏矩阵上进行过测试,但我不明白为什么它在理论上不起作用;以及

  • 当你说相同大小的箱子时,我假设当原始矩阵的尺寸不均匀分开时你会接受“近似”。

这种实现的一些好处,可能是模糊不清或难以阅读:

  • 我认为它适用于源数组的任意维度;虽然我已经对某些案例进行了测试,但我并不是百分之百地确信它是万无一失的;以及

  • 它将允许任意汇总函数,默认为mean;这可能在减少矩阵但仍然需要其集中趋势(例如meanmedian)和分散(例如sdvar,{{ 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空间的任何投影来定义等级,并且可以定义最佳解决方案。