如何使对角线矩阵是数据而其他是0?
How to make matrix with diagonal is data and 0 the other?
我有一个 90 行 4 列的数据框,我想在软件 R 中制作矩阵 (4*90)x4,第一列是 90 个数据,另一列是 0,从 91 到 360。第二列是 0,从1到90,从91到180填充数据然后第181到360行是0。依此类推。
我的语法是这样的
psi10<-c(c(data[,1]),rep(0,3*90))
psi20<-c(rep(0,90),c(data[,2]),rep(0,2*90))
psi30<-c(rep(0,90),rep(0,90),c(data[,3]),rep(0,90))
psi40<-c(rep(0,3*90),c(data[,4]))
Mpsi<-as.matrix(data.frame(psi10,psi20,psi30,psi40))
但是我觉得太长了,如果我添加更多的专栏,那就更难了
请帮我解决我的问题。
谢谢
你可以试试
library(Matrix)
m1 <- as.matrix(bdiag(lapply(data, matrix, 1,90)))
或使用 base R
中的 sapply
n <- 4
m2 <- t(sapply(seq_len(n), function(i) {c(rep(0,90*(i-1)), data[,i],
rep(0, 90*(n-i)))}))
all.equal(m1, m2, check.attributes=FALSE)
#[1] TRUE
更新
OP 似乎想要 "transpose",在那种情况下
m1 <- as.matrix(bdiag(data))
与
相同
m1N <- as.matrix(t(bdiag(lapply(data, matrix, 1,90))))
identical(m1, m1N)
#[1] TRUE
数据
set.seed(24)
data <- as.data.frame(matrix(sample(1:4, 90*4, replace=TRUE), ncol=4))
类似这样的作品?
df<-data.frame(a=100:189,b=100:189,c=100:189,d=100:189)
df<-as.matrix(df)
df<-rbind(df, matrix(0,nrow=(ncol(df)-1)*90,ncol=ncol(df)))
for (x in 1:ncol(df)){
df[,x]<-c(rep(0,90*(x-1)),df[1:90,x],rep(0,90*(ncol(df)-x)))
}
另一个想法可以是:
DF = data.frame(c1 = 1:3, c2 = 4:6, c3 = 7:9)
DF
# c1 c2 c3
#1 1 4 7
#2 2 5 8
#3 3 6 9
mat = matrix(0, nrow = prod(dim(DF)), ncol = ncol(DF))
mat[cbind(seq_len(prod(dim(DF))), rep(seq_along(DF), each = nrow(DF)))] = unlist(DF)
mat
# [,1] [,2] [,3]
# [1,] 1 0 0
# [2,] 2 0 0
# [3,] 3 0 0
# [4,] 0 4 0
# [5,] 0 5 0
# [6,] 0 6 0
# [7,] 0 0 7
# [8,] 0 0 8
# [9,] 0 0 9
我有一个 90 行 4 列的数据框,我想在软件 R 中制作矩阵 (4*90)x4,第一列是 90 个数据,另一列是 0,从 91 到 360。第二列是 0,从1到90,从91到180填充数据然后第181到360行是0。依此类推。
我的语法是这样的
psi10<-c(c(data[,1]),rep(0,3*90))
psi20<-c(rep(0,90),c(data[,2]),rep(0,2*90))
psi30<-c(rep(0,90),rep(0,90),c(data[,3]),rep(0,90))
psi40<-c(rep(0,3*90),c(data[,4]))
Mpsi<-as.matrix(data.frame(psi10,psi20,psi30,psi40))
但是我觉得太长了,如果我添加更多的专栏,那就更难了 请帮我解决我的问题。 谢谢
你可以试试
library(Matrix)
m1 <- as.matrix(bdiag(lapply(data, matrix, 1,90)))
或使用 base R
sapply
n <- 4
m2 <- t(sapply(seq_len(n), function(i) {c(rep(0,90*(i-1)), data[,i],
rep(0, 90*(n-i)))}))
all.equal(m1, m2, check.attributes=FALSE)
#[1] TRUE
更新
OP 似乎想要 "transpose",在那种情况下
m1 <- as.matrix(bdiag(data))
与
相同 m1N <- as.matrix(t(bdiag(lapply(data, matrix, 1,90))))
identical(m1, m1N)
#[1] TRUE
数据
set.seed(24)
data <- as.data.frame(matrix(sample(1:4, 90*4, replace=TRUE), ncol=4))
类似这样的作品?
df<-data.frame(a=100:189,b=100:189,c=100:189,d=100:189)
df<-as.matrix(df)
df<-rbind(df, matrix(0,nrow=(ncol(df)-1)*90,ncol=ncol(df)))
for (x in 1:ncol(df)){
df[,x]<-c(rep(0,90*(x-1)),df[1:90,x],rep(0,90*(ncol(df)-x)))
}
另一个想法可以是:
DF = data.frame(c1 = 1:3, c2 = 4:6, c3 = 7:9)
DF
# c1 c2 c3
#1 1 4 7
#2 2 5 8
#3 3 6 9
mat = matrix(0, nrow = prod(dim(DF)), ncol = ncol(DF))
mat[cbind(seq_len(prod(dim(DF))), rep(seq_along(DF), each = nrow(DF)))] = unlist(DF)
mat
# [,1] [,2] [,3]
# [1,] 1 0 0
# [2,] 2 0 0
# [3,] 3 0 0
# [4,] 0 4 0
# [5,] 0 5 0
# [6,] 0 6 0
# [7,] 0 0 7
# [8,] 0 0 8
# [9,] 0 0 9