2016-03-08 28 views
1

比方說,我們有這樣的矩陣:的R - n個最小值的矩陣的上三角獲取dimnames

set.seed(1) 
m <- matrix(abs(rnorm(16)), ncol=4) 
rownames(m) <- colnames(m) <- c('a', 'b', 'c', 'd') 
m 
#   a   b   c   d 
# a 0.6264538 0.3295078 0.5757814 0.62124058 
# b 0.1836433 0.8204684 0.3053884 2.21469989 
# c 0.8356286 0.4874291 1.5117812 1.12493092 
# d 1.5952808 0.7383247 0.3898432 0.04493361 

是否有可能,以高效的方式,來獲得的維度名稱,說,上三角形的3個最小值?

我有以下方法:

#find the 3rd smallest value in the upper triag: 
val <- m[upper.tri(m)][order(m[upper.tri(m)])[3] ] 

#get the indices of values smaller than val: 
ind_smallest <- arrayInd(which(upper.tri(m) & m <=val), dim(m)) 

cbind(colnames(m)[ind_smallest[, 1]], rownames(m)[ind_smallest[, 2]]) 
#  [,1] [,2] 
# [1,] "a" "b" 
# [2,] "a" "c" 
# [3,] "b" "c" 

是否有更簡單的方法,這既是內存和時間效率?

回答

1

我會做

library(data.table) 

setDT(melt(m))[as.integer(Var2) > as.integer(Var1)][order(value)][1:3] 

# Var1 Var2  value 
# 1: b c 0.3053884 
# 2: a b 0.3295078 
# 3: a c 0.5757814 

工作原理:

  1. melt轉換你的矩陣,以長格式(類型?melt.matrix)。
  2. setDT轉換爲data.table(有關語法,請參閱intro vignettes)。
  3. as.integer(Var2) > as.integer(Var1)獲得上三角形。
  4. order(value)按升序對長格式數據進行排序。
  5. 1:3選擇前三行。

即使var name沒有排序,但沒有測試,我認爲步驟3仍然有效。


類似dplyr代碼:

library(dplyr) 

melt(m) %>% filter(as.integer(Var2) > as.integer(Var1)) %>% arrange(value) %>% slice(1:3) 
相關問題