我的表格看起来像这样:
Row Col Value
1 1 31
1 2 56
1 8 13
2 1 83
2 2 51
2 9 16
3 2 53
我需要将此表转换为矩阵(Row
列表示行,Col
列表示列)。对于像这样的输出:
1 2 3 4 5 6 7 8 9
1 31 56 NA NA NA NA NA 13 NA
2 81 51 NA NA NA NA NA NA 16
3 NA 53 NA NA NA NA NA NA NA
我相信有快速的方法来做我想要的,因为我的解决方案将循环每个行/列组合和cbind
一切。
可重复示例:
require(data.table)
myTable <- data.table(
Row = c(1,1,1,2,2,2,3),
Col = c(1,2,8,1,2,9,1),
Value = c(31,56,13,83,51,16,53))
答案 0 :(得分:4)
直接的:
dat <- data.frame(
Row = c(1,1,1,2,2,2,3),
Col = c(1,2,8,1,2,9,1),
Value = c(31,56,13,83,51,16,53))
m = matrix(NA, nrow = max(dat$Row), ncol = max(dat$Col))
m[cbind(dat$Row, dat$Col)] = dat$Value
m
答案 1 :(得分:4)
稀疏矩阵。您可能需要稀疏矩阵
require(Matrix) # doesn't require installation
mySmat <- with(myTable,sparseMatrix(Row,Col,x=Value))
给出了
3 x 9 sparse Matrix of class "dgCMatrix"
[1,] 31 56 . . . . . 13 .
[2,] 83 51 . . . . . . 16
[3,] 53 . . . . . . . .
矩阵。如果您真的需要一个matrix
- 类对象NA
,那么
myMat <- as.matrix(mySmat)
myMat[myMat==0] <- NA
给出了
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,] 31 56 NA NA NA NA NA 13 NA
[2,] 83 51 NA NA NA NA NA NA 16
[3,] 53 NA NA NA NA NA NA NA NA
效率考虑。对于更短的代码:
myMat <- with(myTable,as.matrix(sparseMatrix(Row,Col,x=Value)))
myMat[myMat==0] <- NA
为了更快的速度(但比创建稀疏矩阵慢),初始化为NA
然后填充,如@jimmyb和@bgoldst所做的那样:
myMat <- with(myTable,matrix(,max(Row),max(Col)))
myMat[cbind(myTable$Row,myTable$Col)] <- myTable$Value
只有坚持NA
超过零时才需要此解决方法。稀疏矩阵几乎肯定是你应该使用的。创建和使用它应该更快;并且存储它应该是更少的内存密集。
答案 2 :(得分:2)
我认为实现这一目标的最简洁和最高效的方法是使用NA预先分配矩阵,然后通过手动计算来自Row
和Col
的线性索引来分配矢量切片:
df <- data.frame(Row=c(1,1,1,2,2,2,3), Col=c(1,2,8,1,2,9,2), Value=c(31,56,13,83,51,16,53) );
m <- matrix(NA,max(df$Row),max(df$Col));
m[(df$Col-1)*nrow(m)+df$Row] <- df$Value;
m;
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
## [1,] 31 56 NA NA NA NA NA 13 NA
## [2,] 83 51 NA NA NA NA NA NA 16
## [3,] NA 53 NA NA NA NA NA NA NA
答案 3 :(得分:1)
xtabs
。的地方
这将是基本方法:
NA
然而,这并没有填补空白,因为并非所有因素水平都可用。您可以单独或即时执行此操作,如下所示:
xtabs(Value ~ Row + Col, myTable)
# Col
# Row 1 2 8 9
# 1 31 56 13 0
# 2 83 51 0 16
# 3 53 0 0 0
通过扩展,这意味着如果&#34; Row&#34;和&#34; Col&#34;值是因素,xtabs(Value ~ factor(Row, sequence(max(Row))) +
factor(Col, sequence(max(Col))), myTable)
# factor(Col, sequence(max(Col)))
# factor(Row, sequence(max(Row))) 1 2 3 4 5 6 7 8 9
# 1 31 56 0 0 0 0 0 13 0
# 2 83 51 0 0 0 0 0 0 16
# 3 53 0 0 0 0 0 0 0 0
也应该有效:
dcast.data.table
(但由于某种原因,它不在我的测试中。我必须做dcast.data.table(myTable, Row ~ Col, value.var = "Value", drop = FALSE)
才能使它工作,因此没有利用&#34; data.table&#34;速度。 )