2012-05-14 112 views
5

我正在使用匹配運算符來從單獨的數據框中獲取矩陣中出現的值。但是,生成的矩陣按照它們在數據框中顯示的順序具有值,而不是在原始矩陣中。有沒有辦法使用匹配運算符來保留原始矩陣的順序?R - 使用匹配運算符時保留順序(%in%)

下面是一個簡單的例子:

vec=c("b","a","c"); vec 

df=data.frame(row.names=letters[1:5],values=1:5); df 

df[rownames(df) %in% vec,1] 

這產生> [1] 1 2 3這是爲了"a" "b" "c"出現在數據幀。但是,我想生成>[1] 2 1 3這是它們出現在原始矢量中的順序。

謝謝!

回答

6

使用match

df[match(vec, rownames(df)), ] 
# [1] 2 1 3 

要知道,如果你有在任何vecrownames(df)重複值,match可能無法按預期的行爲。

編輯: 我剛剛意識到行名稱索引將解決你的問題多一點簡單和優雅:

df[vec, ] 
# [1] 2 1 3 
+0

的積分,但兩種解決方案均可使用。謝謝! – jslefche

3

使用match(和擺脫NA爲在任一向量元素對於那些沒有在另一場比賽中值):

Filter(function(x) !is.na(x), match(rownames(df), vec)) 
+1

實際上,如果您匹配不匹配= 0,匹配將返回0而不是NA,以匹配不匹配的項目。由於[]的行選擇忽略0,因此只需將匹配結果目錄粘貼到[]中,即可省去調用以使用行名索引過濾 – frankc

0

由於行名稱,編制索引還適用於載體,我們可以進一步採取這種一步到位並定義:

'%ino%' <- function(x, table) { 
    xSeq <- seq(along = x) 
    names(xSeq) <- x 
    Out <- xSeq[as.character(table)] 
    Out[!is.na(Out)] 
} 

我們現在所期望的結果:

df[rownames(df) %ino% vec, 1] 
[1] 2 1 3 

在函數內部,姓名()並自動轉換爲字符和表與as.character()改變,所以這也正常工作時,輸入%伊諾%的數字:

LETTERS[1:26 %in% 4:1] 
[1] "A" "B" "C" "D" 


LETTERS[1:26 %ino% 4:1] 
[1] "D" "C" "B" "A" 

繼%以%,缺失值被移除:

LETTERS[1:26 %in% 3:-5] 
[1] "A" "B" "C" 

LETTERS[1:26 %ino% 3:-5] 
[1] "C" "B" "A" 

隨着%以%計的沿所述對象的尺寸重複的邏輯順序被子集,這不符合%伊諾%的情況下:

data.frame(letters, LETTERS)[1:5 %in% 3:-5,] 

    letters LETTERS 
1  a  A 
2  b  B 
3  c  C 
6  f  F 
7  g  G 
8  h  H 
11  k  K 
12  l  L 
13  m  M 
16  p  P 
17  q  Q 
18  r  R 
21  u  U 
22  v  V 
23  w  W 
26  z  Z 


data.frame(letters, LETTERS)[1:5 %ino% 3:-5,] 

    letters LETTERS 
3  c  C 
2  b  B 
1  a  A