我正在使用的矩阵看起来像这样
m <- matrix(rep(c(0,1),10),ncol=2,nrow=5)
colnames(m)<-c(2,5)
所以矩阵在pos 2和5处有行。所有不在colnames中的pos都必须全为0
2 5
[1,] 0 1
[2,] 1 0
[3,] 0 1
[4,] 1 0
[5,] 0 1
应该是
1 2 3 4 5
[1,] 0 0 0 0 1
[2,] 0 1 0 0 0
[3,] 0 0 0 0 1
[4,] 0 1 0 0 0
[5,] 0 0 0 0 1
该函数需要接受一个结束参数(在这个例子中它是5)
是否存在一种在非常大的基质中快速的解决方案?我谈论了类似于此事的1400次10 Mil oder
答案 0 :(得分:1)
我们根据初始矩阵('m1')中列名的最大值创建一个'{0'的正方形matrix
。在示例中,它是'5'。因此,我们创建的'm2'是维度5X5
。
n <- max(as.numeric(colnames(m1)))
m2 <- matrix(0, n,n)
使用melt
中的reshape2
,我们将'm1'的'宽'格式转换为'long'格式,subset
生成的'data.frame',删除行'value'为'0'。根据第一列和第二列创建行/列索引,将其转换为matrix
并使用它将'm2'中的'0'值替换为1.
library(reshape2)
m2[as.matrix(subset(melt(m1), value!=0)[,-3])] <- 1
m2
# [,1] [,2] [,3] [,4] [,5]
#[1,] 0 0 0 0 1
#[2,] 0 1 0 0 0
#[3,] 0 0 0 0 1
#[4,] 0 1 0 0 0
#[5,] 0 0 0 0 1
或者base R
选项会创建没有melt
,cbind
行/列索引的行/列索引,并将'm2'中的值替换为1。
m2[cbind(seq(n), c(as.numeric(colnames(m1))[col(m1)]*m1))] <- 1
编辑:
如果'm1'中的值不是全1
m2[cbind(seq(n), c(as.numeric(colnames(m1))[col(m1)]*m1))] <- m1[!!m1]
为了便于理解,上面的代码可以分成不同的部分。 col(m1)
给出原始矩阵的列索引。
col(m1)
# [,1] [,2]
#[1,] 1 2
#[2,] 1 2
#[3,] 1 2
#[4,] 1 2
#[5,] 1 2
通过使用该数字索引,我们可以在转换为'numeric'后将该值更改为'm1'的列名。输出为vector
。
as.numeric(colnames(m1))[col(m1)]
#[1] 2 2 2 2 2 5 5 5 5 5
乘以'm1'将'1'值替换为我们在上一步中获得的值
as.numeric(colnames(m1))[col(m1)]*m1
# 2 5
#[1,] 0 5
#[2,] 2 0
#[3,] 0 5
#[4,] 2 0
#[5,] 0 5
我们可以将它(c
)连接到vector
以创建列索引
c(as.numeric(colnames(m1))[col(m1)]*m1)
#[1] 0 2 0 2 0 5 0 5 0 5
获取'row'索引的'{1}}'n'。
seq
当我们 seq(n)
#[1] 1 2 3 4 5
带有列索引的行索引时,由于循环,行索引会重复自己到列索引的长度
cbind
这可用于从'm2'
获取相应的元素 cbind(seq(n), c(as.numeric(colnames(m1))[col(m1)]*m1))
# [,1] [,2]
#[1,] 1 0
#[2,] 2 2
#[3,] 3 0
#[4,] 4 2
#[5,] 5 0
#[6,] 1 5
#[7,] 2 0
#[8,] 3 5
#[9,] 4 0
#[10,] 5 5
我们分配给1
在编辑部分,我使用了 m2[cbind(seq(n), c(as.numeric(colnames(m1))[col(m1)]*m1))]
#[1] 0 0 0 0 0
,它为所有不为0的值返回逻辑矩阵!!m1
。通过对TRUE/FALSE
进行子集,我们得到m1[!!m1]
的{{1}}这些值可用于替换。
或者更快的方法是使用vector
创建sparseMatrix
。如上所述,我们创建行('i')和列('j')索引,子集'i'和'j'仅包含非零值(因为它不适用于{{1 }),并指定library(Matrix)
。在这里,我们不必创建初始矩阵'm2'。
sparseMatrix
使用x=1
换行将其转换为常规矩阵
library(Matrix)
j <- c(as.numeric(colnames(m1))[col(m1)]*m1)
i <- rep(seq(n), length.out=length(j))
sparseMatrix(i[j!=0], j[j!=0], x=1)
# 5 x 5 sparse Matrix of class "dgCMatrix"
#[1,] . . . . 1
#[2,] . 1 . . .
#[3,] . . . . 1
#[4,] . 1 . . .
#[5,] . . . . 1
as.matrix
答案 1 :(得分:1)
这是一种类似的解决方案,没有熔化基质。
首先,我们将从最后一列获取值并分配一个矩阵(类似于@akruns方法)
indx <- as.numeric(colnames(m)[ncol(m)])
m2 <- matrix(0, ncol = indx, nrow = nrow(m))
然后,我们将简单地将列名添加到新矩阵并根据匹配的列名插入旧矩阵
colnames(m2) <- seq_len(indx)
m2[, colnames(m)] <- m
m2
# 1 2 3 4 5
# [1,] 0 0 0 0 1
# [2,] 0 1 0 0 0
# [3,] 0 0 0 0 1
# [4,] 0 1 0 0 0
# [5,] 0 0 0 0 1