2011-12-01 45 views
5

我有一個大矩陣,我想從中隨機提取一個更小的矩陣。 (我想這樣做1000次,所以最終這將是一個for循環。)例如說我有這個9x9的矩陣:選擇由R中隨機向量指定的列

mat=matrix(c(0,0,1,0,1,0,0,0,1,0,0,0,0,1,1,1,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,1, 
      0,0,0,0,1,1,1,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,1,1,1,0,0, 
      1,0,1,0,0,0,0,0,1,0,1,0,0,0,1), nrow=9) 

從這個矩陣,我想一個隨機3x3的子集。訣竅是我不希望最終矩陣中的任何行或列總和爲0.另一個重要的是我需要知道最終矩陣中的行和列的原始數量。因此,如果我最終隨機選擇第4,5和7行以及第1,3和8列,我希望在最終矩陣中可以輕鬆訪問這些標識符。

這是我到目前爲止所做的。

首先,我創建了一個行號和列號的向量。我試圖將這些附加到整個矩陣。

r.num<-seq(from=1,to=nrow(mat),by=1)  #vector of row numbers 
c.num<-seq(from=0, to=(ncol(mat)+1),by=1) #vector of col numbers (adj for r.num) 

mat.1<-cbind(r.num,mat) 
mat.2<-rbind(c.num,mat.1) 

現在我有一個帶有標識符的10x10矩陣。我可以通過創建一個隨機矢量並對矩陣進行子集來選擇我的行。

rand <- sample(r.num,3) 
temp1 <- rbind(mat.2[1,],mat.2[rand,])  #keep the identifier row 

這效果很好!現在我想隨機選擇3列。這是我遇到麻煩的地方。我試圖以同樣的方式做。

rand2 <- sample(c.num,3) 
temp2 <- cbind(temp1[,1],temp1[,rand2]) 

問題是,我結束了一些行和列的總和是0.我可以消除先總和爲0的列。

temp3 <- temp1[,which(colSums(temp1[2:nrow(temp1),])>0)] 
cols <- which(colSums(temp1[2:nrow(temp1),2:ncol(temp1)])>0) 
rand3 <- sample(cols,3) 
temp4 <- cbind(temp3[,1],temp3[,rand3]) 

但是,我最終得到一個錯誤消息。出於某種原因,R不喜歡以這種方式對矩陣進行子集。

所以我的問題是,有沒有更好的方法來通過隨機向量「rand3」對零矩陣進行子集去除或者有更好的方法來隨機選擇三個互補的行和列,沒有總和爲0?

非常感謝您的幫助!

+0

如果最終1000個集矩陣是唯一的? –

+0

這並不重要。我從中抽取的原始矩陣是1174行和455列,所以我想要獲得具有代表性的抽樣。但是,我確信有一個有限的可能性。唯一的麻煩是如果對某個獨特的子矩陣存在某種抽樣偏差。 – Laura

回答

4

如果我明白你的問題,我認爲這會工作:

mat=matrix(c(0,0,1,0,1,0,0,0,1,0,0,0,0,1,1,1,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,1, 
      0,0,0,0,1,1,1,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,1,1,1,0,0, 
      1,0,1,0,0,0,0,0,1,0,1,0,0,0,1), nrow=9) 

smallmatrix = matrix(0,,nrow=3,ncol=3) 

while(any(apply(smallmatrix,2,sum) ==0) | any(apply(smallmatrix,1,sum) ==0)){ 
     cols = sample(ncol(mat),3) 
     rows= sample(nrow(mat),3) 
     smallmatrix = mat[rows,cols] 
} 

colnames(smallmatrix) = cols 
rownames(smallmatrix) = rows 
+2

哈哈我幾乎想發佈相同的答案,但你打敗了我!我只想在評估行和列的總和是否爲零時使用'rowSums'和'colSums'更快:any(colSums(smallmatrix)== 0)|任何(rowSums(smallmatrix)== 0)' –

+0

糟糕,我只注意到有一些行使用這種方法以零和結束。任何其他想法? – Laura

+1

我剛修好了。 @SachaEpskamp從一開始就做對了。我沒有注意到限制也適用於行。所以只需要添加一個或一段時間。 – aatrujillob