2015-08-16 69 views
4

自動我有一個41x41相似性矩陣(或數據幀),就像下面(I括在所述附接的完整版本):如何處理矩陣(數據幀)中的R

 V1 V2  V3  V4  V5  V6 
V1 1 0.068 0.211 0.285 0.198 0.047 
V2 0.068 1  0.851 0.450 0.277 0.014 
V3 0.211 0.851  1 0.660 0.420 0.113 
V4 0.285 0.450 0.660  1 0.896 0.466 
V5 0.198 0.277 0.420 0.896 1  0.241 
V6 0.047 0.014 0.113 0.466 0.241  1 

我想爲每個矢量(Vx)建立一個推薦列表,最先是最相似的,最後是不相似的。所以我想我需要提取兩列(或兩行),通過減少排序值,並提取列名稱。 但是,當我嘗試自動選擇列時,它不起作用。

ms<-readLines("E:/exp/ccsm.txt", encoding = "UTF-8") 
d = as.data.frame(ms) 
for(dcol in 2:length(ms)) 
{ 
    temp<-d[,c(1,dcol)] 
    nlist<-temp[order(d[,dcol], decreasing=T)] 
    lname<-nlist[,1] 
} 
Show Traceback 
Rerun with Debug 
Error in `[.data.frame`(d, , c(1, dcol)) : undefined columns selected 

看來變量不能是列/行數?但是可能需要處理更大的相似性矩陣。如果通過某種循環無法實現,那將是一場災難。 我不知道你是否可以給我一些解決這個問題的建議。如果您能儘早回覆,我將不勝感激。期待您的迴音。

回答

1

它看起來對我來說,你的主要問題是,你沒有在你的文件中讀取正確的data.frame。

我救了你的樣本數據爲ccsm.txt在我的R會話PWD,然後運行以下:

ms <- readLines('ccsm.txt',encoding='UTF-8'); 
ms; 
## [1] "  V1 V2  V3  V4  V5  V6" 
## [2] " V1 1 0.068 0.211 0.285 0.198 0.047" 
## [3] " V2 0.068 1  0.851 0.450 0.277 0.014" 
## [4] " V3 0.211 0.851  1 0.660 0.420 0.113" 
## [5] " V4 0.285 0.450 0.660  1 0.896 0.466" 
## [6] " V5 0.198 0.277 0.420 0.896 1  0.241" 
## [7] " V6 0.047 0.014 0.113 0.466 0.241  1" 
d <- as.data.frame(ms); 
d; 
##             ms 
## 1   V1 V2  V3  V4  V5  V6 
## 2 V1 1 0.068 0.211 0.285 0.198 0.047 
## 3 V2 0.068 1  0.851 0.450 0.277 0.014 
## 4 V3 0.211 0.851  1 0.660 0.420 0.113 
## 5 V4 0.285 0.450 0.660  1 0.896 0.466 
## 6 V5 0.198 0.277 0.420 0.896 1  0.241 
## 7 V6 0.047 0.014 0.113 0.466 0.241  1 
names(d); 
## [1] "ms" 
dim(d); 
## [1] 7 1 
sapply(d,class); 
##  ms 
## "factor" 

正如你所看到的,你readLines()/as.data.frame()調用導致了7 1個data.frame其單列由來自文件的原始文本行的因素組成。

相反,你需要使用read.table()(還有其他的選擇,以及,如fread()data.table):

d <- read.table('ccsm.txt'); 
d; 
##  V1 V2 V3 V4 V5 V6 
## V1 1.000 0.068 0.211 0.285 0.198 0.047 
## V2 0.068 1.000 0.851 0.450 0.277 0.014 
## V3 0.211 0.851 1.000 0.660 0.420 0.113 
## V4 0.285 0.450 0.660 1.000 0.896 0.466 
## V5 0.198 0.277 0.420 0.896 1.000 0.241 
## V6 0.047 0.014 0.113 0.466 0.241 1.000 
names(d); 
## [1] "V1" "V2" "V3" "V4" "V5" "V6" 
dim(d); 
## [1] 6 6 
sapply(d,class); 
##  V1  V2  V3  V4  V5  V6 
## "numeric" "numeric" "numeric" "numeric" "numeric" "numeric" 

不幸的是,你的代碼仍然不能正常工作:

for (dcol in 2:length(ms)) { 
    temp <- d[,c(1,dcol)]; 
    nlist <- temp[order(d[,dcol],decreasing=T)]; 
    lname <- nlist[,1]; 
}; 
## Error in `[.data.frame`(temp, order(d[, dcol], decreasing = T)) : 
## undefined columns selected 

這裏有兩個問題。首先,ms包含文件中的原始文本行,因爲包含標題行,因此編號爲7。但是文件中只有6行。因此d[,c(1,dcol)]將在dcol達到7時失敗。

dcol永遠不會達到7,因爲在第一次迭代temp[order(d[,dcol],decreasing=T)]失敗。這是因爲temp是data.frame,因爲它是從d的兩列切片中分配的。但是您正在使用一個參數爲temp建立索引,該參數爲僅包含兩個組件的基礎列表編制索引。調用order()的返回值由整數1到6組成,因爲它在d(並且在d中有6行)的列上操作,所以整數3到6對於雙分量都是超出範圍列表的基礎temp data.frame。

下面我將如何計算所需的輸出:

apply(d,1,order,decreasing=T); 
##  V1 V2 V3 V4 V5 V6 
## [1,] 1 2 3 4 5 6 
## [2,] 4 3 2 5 4 4 
## [3,] 3 4 4 3 3 5 
## [4,] 5 5 5 6 2 3 
## [5,] 2 1 1 2 6 1 
## [6,] 6 6 6 1 1 2 

如果您想推薦的載體,而不是索引的名稱,你可以這樣做:

apply(d,1,function(x) names(d)[order(x,decreasing=T)]); 
##  V1 V2 V3 V4 V5 V6 
## [1,] "V1" "V2" "V3" "V4" "V5" "V6" 
## [2,] "V4" "V3" "V2" "V5" "V4" "V4" 
## [3,] "V3" "V4" "V4" "V3" "V3" "V5" 
## [4,] "V5" "V5" "V5" "V6" "V2" "V3" 
## [5,] "V2" "V1" "V1" "V2" "V6" "V1" 
## [6,] "V6" "V6" "V6" "V1" "V1" "V2" 

如果你不不喜歡那第一排,因爲它一定會將「自我」向量排在最高位置,所以您可以用...[-1,]將它索引出來。

+0

好的。驚訝沒有人發現了9個小時 –

1

你可以試試這個:

diag(mat) <- -99 
mat2 <- t(apply(mat,2,function(x) rev(order(x))))[,-ncol(mat)] 
#> mat2 
# [,1] [,2] [,3] [,4] [,5] 
#V1 4 3 5 2 6 
#V2 3 4 5 1 6 
#V3 2 4 5 1 6 
#V4 5 3 6 2 1 
#V5 4 3 2 6 1 
#V6 4 5 3 1 2 

這裏每一行都包含,從左至右降序排列,這是最相似的根據行名稱指定的向量列的索引號的相似矩陣。這通過sort()結合rev()來實現,其將條目從其最大值排序到最小值。這種排序適用於原始矩陣的每一列。對角線設置爲-99以通過將向量與其自身的相似性設置爲任意的負常數來規避每個向量與其自身最相似的微不足道的結果。此過程將所考慮的行的索引號作爲最後一個條目。出於這個原因,最後一個條目從矩陣中移除(將矢量與自身進行比較沒有意義)。爲了便於按行顯示相似性,矩陣被換位。

數據

mat <- as.matrix(read.table(text="V1 V2  V3  V4  V5  V6 
V1 1 0.068 0.211 0.285 0.198 0.047 
V2 0.068 1  0.851 0.450 0.277 0.014 
V3 0.211 0.851  1 0.660 0.420 0.113 
V4 0.285 0.450 0.660  1 0.896 0.466 
V5 0.198 0.277 0.420 0.896 1  0.241 
V6 0.047 0.014 0.113 0.466 0.241  1", header=T))