在 R 中整理矩阵的最佳方法是什么
What is the best way to tidy a matrix in R
是否有"tidying"一个matrix/array的最佳实践方法? "tidy" 在这种情况下我的意思是
- 矩阵的每个元素一行
- 每个维度一列。这些列的元素为您提供存储在该行
上的矩阵元素的 "coordinates"
我这里有一个二维矩阵的例子,但理想情况下这也适用于数组(这个例子适用于 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,可以交替使用 row
和 col
:
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
另一种方法是像这样将arrayInd
和cbind
一起使用。
# 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
是否有"tidying"一个matrix/array的最佳实践方法? "tidy" 在这种情况下我的意思是
- 矩阵的每个元素一行
- 每个维度一列。这些列的元素为您提供存储在该行 上的矩阵元素的 "coordinates"
我这里有一个二维矩阵的例子,但理想情况下这也适用于数组(这个例子适用于 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,可以交替使用 row
和 col
:
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
另一种方法是像这样将arrayInd
和cbind
一起使用。
# 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