2012-10-26 60 views
2

假设我有一个矩阵,像这样:如何随机替换对称矩阵的元素?

data=matrix(c(1,0,0,0,0,0,1,0,0.6583,0,0,0,1,0,0,0,0.6583,0,1,0,0,0,0,0,1),nrow=5,ncol=5) 

    [,1] [,2] [,3] [,4] [,5] 
[1,] 1 0.0000 0 0.0000 0 
[2,] 0 1.0000 0 0.6583 0 
[3,] 0 0.0000 1 0.0000 0 
[4,] 0 0.6583 0 1.0000 0 
[5,] 0 0.0000 0 0.0000 1 

如何创建另一个矩阵,说“数据2”,使得其具有相同数量的非对角线非零元素为“数据”,但在其他位置除了数据之外呢?随机模拟的数据将是统一的(如此runif)。

+0

会不会有永远的对角线上1秒?对于具有未知数量的非零值的普通方阵,问题是否存在? – Bitwise

+0

这是一个(模拟的)偏相关矩阵,其中我预先确定了非零非对角线元素的数量。因此,对角线上总会有1,它将是一个方形矩阵。 – 2012-10-26 06:24:07

+2

在这个问题中存在一些关键的未规定的限制:如果模拟矩阵包含相关性,则其必须具有介于-1和1之间的非对角线值,并且它们必须是正半定值或其他(如果我正确理解“偏相关” )必须是这种矩阵的投影(通过清零一些条目对来创建)。另外,“统一”了什么参数? (有很多方法可以参数化这些矩阵。) – whuber

回答

0

没有真正理解这个问题。在这个例子中有两个非对角元素和非零元素(0.6583),对吗?在这种情况下,矩阵是否包含两个元素?

data=matrix(c(1,0,0,0,0,0,1,0,0.6583,0,0,0,1,0,0,0,0.6583,0,1,0,0,0,0,0,1),nrow=5,ncol=5) 

# Convert to vector 
data2 <- as.numeric(data) 

# Remove diagonal 
data2 <- data2[as.logical(upper.tri(data) | lower.tri(data))] 

# Remove 0 elements 
data2 <- data2[data2 != 0] 

data2 
+1

对不起,我应该澄清。基本上在索引[2,4]或[4,2]上有一个非零非对角元素。我希望“data2”在其索引[2,4]或[4,2]以外的任何位置的矩阵中也有一个非零非对角线元素。这更清楚吗? – 2012-10-26 06:27:36

1

这是一个有点笨拙的做法。它适用于小型矩阵,但如果要将其用于某些非常高维的问题,速度会太慢。

# Current matrix: 
data=matrix(c(1,0,0,0,0,0,1,0,0.6583,0,0,0,1,0,0,0,0.6583,0,1,0,0,0,0,0,1),nrow=5,ncol=5) 

# Number of nonzero elements in upper triangle: 
no.nonzero<-sum(upper.tri(data)*data>0) 

# Generate same number of new nonzero correlations: 
new.cor<-runif(no.nonzero,-1,1) 

# Create new diagonal matrix: 
p<-dim(data)[1] 
data2<-diag(1,p,p) 

### Insert nonzero correlations: ### 

# Step 1. Identify the places where the nonzero elements can be placed: 

pairs<-(p^2-p)/2 # Number of element in upper triangle 
combinations<-matrix(NA,pairs,2) # Matrix containing indices for those elements (i.e. (1,2), (1,3), ... (2,3), ... and so on) 

k<-0 
for(i in 1:(p-1)) 
{ 
    for(j in {i+1}:p) 
    { 
     k<-k+1 
     combinations[k,]<-c(i,j) 
    } 
} 

# Step 2. Randomly pick indices: 

places<-sample(1:k,no.nonzero) 

# Step 3. Insert nonzero correlations: 

for(i in 1:no.nonzero) 
{ 
    data2[combinations[places[i],1],combinations[places[i],2]]<-data2[combinations[places[i],2],combinations[places[i],1]]<-new.cor[i] 
} 
+0

如果你想避免位置[2,4]被重复,你可以简单地从'组合'中删除这些索引 –