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

What is the best way to tidy a matrix in R

是否有"tidying"一个matrix/array的最佳实践方法? "tidy" 在这种情况下我的意思是

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

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

另一种方法是像这样将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])

哪个returns

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