在R中整理矩阵的最佳方法是什么?

时间:2017-03-15 12:52:44

标签: r dplyr tidyverse

是否有最好的练习方式"整理"矩阵/数组?通过" tidy"在这种情况下,我的意思是

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

我在这里有一个2d矩阵的例子,但理想情况下这也适用于数组(这个例子适用于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

2 个答案:

答案 0 :(得分:4)

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

名称请注意,上面使用了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

答案 1 :(得分:0)

另一种方法是将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