【问题标题】:What is the best way to tidy a matrix in R在 R 中整理矩阵的最佳方法是什么
【发布时间】:2017-03-15 12:52:44
【问题描述】:

是否有“整理”矩阵/数组的最佳实践方法?在这种情况下,我所说的“整洁”是指

  • 矩阵的每个元素一行
  • 每个维度一列。这些列的元素为您提供了存储在该行上的矩阵元素的“坐标”

我在这里有一个二维矩阵的示例,但理想情况下这也适用于数组(此示例适用于 mm <- array(1:18, c(3,3,3)),但我认为此处粘贴太多)


mm <- matrix(1:9, nrow = 3)
mm
#>      [,1] [,2] [,3]
#> [1,]    1    4    7
#> [2,]    2    5    8
#> [3,]    3    6    9
inds <- which(mm > -Inf, arr.ind = TRUE)
cbind(inds, value = mm[inds])
#>       row col value
#>  [1,]   1   1     1
#>  [2,]   2   1     2
#>  [3,]   3   1     3
#>  [4,]   1   2     4
#>  [5,]   2   2     5
#>  [6,]   3   2     6
#>  [7,]   1   3     7
#>  [8,]   2   3     8
#>  [9,]   3   3     9

【问题讨论】:

  • 在什么意义上最好?什么样的矩阵?像您建议的表示对于稀疏矩阵来说更节省空间,但对于密集矩阵则不然 - 原始形式在那里表现出色。
  • 如果您想要矩阵的稀疏表示,请使用 Matrix 包

标签: r dplyr tidyverse


【解决方案1】:

as.data.frame.table 从宽转换为长的一种方法如下。请参阅?as.data.frame.table 了解更多信息。没有使用任何包。

mm <- matrix(1:9, 3)
long <- as.data.frame.table(mm)

代码给出了这个data.frame:

> long
  Var1 Var2 Freq
1    A    A    1
2    B    A    2
3    C    A    3
4    A    B    4
5    B    B    5
6    C    B    6
7    A    C    7
8    B    C    8
9    C    C    9

数字

如果您更喜欢行号和列号:

long[1:2] <- lapply(long[1:2], as.numeric)

给予:

> long
  Var1 Var2 Freq
1    1    1    1
2    2    1    2
3    3    1    3
4    1    2    4
5    2    2    5
6    3    2    6
7    1    3    7
8    2    3    8
9    3    3    9

names 请注意,上面使用了 A、B、C、...,因为没有行名或列名。如果存在,它们将被使用。也就是说,如果有行和列名称以及维度名称,输出将如下所示:

mm2 <- array(1:9, c(3, 3), dimnames = list(A = c("a", "b", "c"), B = c("x", "y", "z")))
as.data.frame.table(mm2, responseName = "Val")

给予:

  A B Val
1 a x   1
2 b x   2
3 c x   3
4 a y   4
5 b y   5
6 c y   6
7 a z   7
8 b z   8
9 c z   9

3d

这是一个 3d 示例:

as.data.frame.table(array(1:8, c(2,2,2)))

给予:

  Var1 Var2 Var3 Freq
1    A    A    A    1
2    B    A    A    2
3    A    B    A    3
4    B    B    A    4
5    A    A    B    5
6    B    A    B    6
7    A    B    B    7
8    B    B    B    8

仅限 2d 对于 2d,可以交替使用 rowcol

sapply(list(row(mm), col(mm), mm), c)

cbind(c(row(mm)), c(col(mm)), c(mm))

其中任何一个都给出了这个矩阵:

      [,1] [,2] [,3]
 [1,]    1    1    1
 [2,]    2    1    2
 [3,]    3    1    3
 [4,]    1    2    4
 [5,]    2    2    5
 [6,]    3    2    6
 [7,]    1    3    7
 [8,]    2    3    8
 [9,]    3    3    9

【讨论】:

    【解决方案2】:

    另一种方法是像这样使用arrayIndcbind

    # a 3 X 3 X 2 array
    mm <- array(1:18, dim=c(3,3,2))
    

    与您的代码类似,但使用更自然的arrayInd 函数,我们有

    # get array in desired format
    myMat <- cbind(c(mm), arrayInd(seq_along(mm), .dim=dim(mm)))
    
    # add column names
    colnames(myMat) <- c("values", letters[24:26])
    

    返回

    myMat
          values x y z
     [1,]      1 1 1 1
     [2,]      2 2 1 1
     [3,]      3 3 1 1
     [4,]      4 1 2 1
     [5,]      5 2 2 1
     [6,]      6 3 2 1
     [7,]      7 1 3 1
     [8,]      8 2 3 1
     [9,]      9 3 3 1
    [10,]     10 1 1 2
    [11,]     11 2 1 2
    [12,]     12 3 1 2
    [13,]     13 1 2 2
    [14,]     14 2 2 2
    [15,]     15 3 2 2
    [16,]     16 1 3 2
    [17,]     17 2 3 2
    [18,]     18 3 3 2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-21
      • 2015-10-20
      • 2013-09-22
      • 1970-01-01
      • 1970-01-01
      • 2013-06-08
      • 1970-01-01
      相关资源
      最近更新 更多