2017-03-21 71 views
2

比方說,我們有兩個數據幀:找位置元件到另一個

df1 <- data.frame(A = letters[1:3], B = letters[4:6], C = letters[7:9], stringsAsFactors = FALSE) 
    A B C 
1 a d g 
2 b e h 
3 c f i 

df2 <- data.frame(V1 = 1:3, V2 = 4:6, V3 = 7:9) 
    V1 V2 V3 
1 1 4 7 
2 2 5 8 
3 3 6 9 

我需要建立一個函數,它作爲輸入的單個值或從所述一個含元件的載體數據幀並根據其位置索引從另一個數據幀返回元素。

函數應該像這樣工作:

> matchdf(values = c("a", "e", "i"), dfin = df1, dfout = df2) 
[1] 1 5 9 

> matchdf(values = c(1, 5, 9), dfin = df2, dfout = df1) 
[1] "a" "e" "i" 

> matchdf(values = c(1, 1, 1), dfin = df2, dfout = df1) 
[1] "a" "a" "a" 

這是我到目前爲止已經試過:

requiere(dplyr) 
toVec <- function(df) df %>% as.matrix %>% as.vector 
matchdf <- function(values, dfin, dfout) toVec(dfout)[toVec(dfin) %in% values] 

# But sometimes the output values aren't in correct order: 
> matchdf(c("c", "i", "h"), dt1, dt2) 
[1] 3 8 9 
# should output 3 9 8 

> matchdf(values = c("a", "a", "a"), dfin = dt1, dfout = dt2) 
[1] 1 
# Should output 1 1 1 

隨意使用data.table或/和dplyr如果它簡化了任務。我更喜歡沒有for循環的解決方案。

假設:從DF1

  • 元素是從不同DF2
  • 暗淡(DF1)=暗淡(DF2)
+3

在我在正確的軌道上你的看法。而不是將您的數據框轉換爲矢量,首先使用矢量。另外,我會做一些像'values = c(「a」,「e」,「i」); unlist(df2)[match(values,unlist(df1))]'而不是使用dplyr並創建兩個函數。 –

+0

@DavidArenburg它的工作原理,你應該發佈你的答案 – mat

回答

-1
matchdf <- function(values, dfin, dfout){ 
     unlist(sapply(values, 
         function(val) dfout[dfin == val], 
         USE.NAMES = F) 
       ) 
} 

matchdf(c("c", "i", "h"), df1, df2) 
#should output 3 9 8 
[1] 3 9 8 
matchdf(values = c("a", "a", "a"), dfin = df1, dfout = df2) 
#should output 1 1 1 
[1] 1 1 1 
matchdf(values = c("X", "Y", "a"), dfin = df1, dfout = df2) 
#should output vector, not list 
[1] 1 
+0

這是不好的答案,因爲這只是一個沒有任何解釋的代碼轉儲(這對未來的讀者沒用),因爲它教會用戶在完全向量化的操作上運行循環。 –

+0

是的,我同意 - 你的回答比我的更好。我試圖做一些非常相似的事情,但是我用'%in%'做了'因爲我不知道'match'函數。我現在知道,多虧了你上面的評論。我試圖比較兩種解決方案的時間 - 我的情況更糟糕:https://www.dropbox.com/s/trejyylvwtcdo5b/timing.png?dl=0我將在一小時內刪除此答案。 – utubun

相關問題