2011-05-25 19 views
6

मैं आर में दो dataframe दो dataframe विलयप्रत्येक dataframe में दो exchangable कॉलम मिलान के आधार पर

dataframe 1

A B C D E F G 
1 2 a a a a a 
2 3 b b b c c 
4 1 e e f f e 

dataframe 2

X Y Z 
1 2 g 
2 1 h 
3 4 i 
1 4 j 

मैं dataframe1 के कॉलम से मिलान करना चाहते डेटाफ्रेम 2 के कॉलम एक्स और वाई के साथ ए और बी। यह एक जोड़ीदार तुलना नहीं है, यानी पंक्ति 1 (ए = 1 बी = 2) पंक्ति 1 (एक्स = 1, वाई = 2) और पंक्ति 2 (एक्स) के समान मानी जाती है = 2, वाई = 1) डेटाफ्रेम 2.

मिलान मिलने पर, मैं डेटाफ्रेम 1 की कॉलम सी, डी, ई, एफ को डेटाफ्रेम 2 की मिलान पंक्ति में वापस जोड़ना चाहता हूं, निम्नानुसार: ना के रूप में मेल नहीं खाता।

अंतिम dataframe

X Y Z C D E F G 
1 2 g a a a a a 
2 1 h a a a a a 
3 4 i na na na na na 
1 4 j e e f f e 

मैं केवल पता कर सकते हैं कि कैसे एक कॉलम के लिए मिलान करने के लिए, हालांकि, कैसे दो exchangable स्तंभों के लिए मिलान और मिलान परिणामों के आधार पर दो dataframes विलय करने के लिए मेरे लिए मुश्किल है। Pls कृपया ऐसा करने का स्मार्ट तरीका प्रदान करने में मदद करें।

चर्चा की आसानी के लिए (विन्सेंट और DWin (मेरे पिछले quesiton द्वारा टिप्पणियाँ) है कि मैं बोली का परीक्षण करना चाहिए के लिए धन्यवाद।) वहाँ आर

को
df1 <- data.frame(A = c(1,2,4), B=c(2,3,1), C=c('a','b','e'), 
           D=c('a','b','e'), E=c('a','b','f'), 
           F=c('a','c','f'), G=c('a','c', 'e')) 

df2 <- data.frame(X = c(1,2,3,1), Y=c(2,1,4,4), Z=letters[7:10]) 
+1

आप टकराव कैसे संभालते हैं? हां, जब डीएफ 1 में एक्स = 1 और वाई = 2 और एक्स = 2 और पंक्तियों में वाई = 1 है? क्या आप गारंटी देते हैं कि ऐसा नहीं होगा? – mcpeterson

उत्तर

6
लोड हो रहा है dataframe 1 के लिए कोटा और 2 हैं

निम्नलिखित कार्य करता है, लेकिन इसमें कोई संदेह नहीं हो सकता है।

मैं पहले थोड़ा सा सहायक फ़ंक्शन बनाता हूं जो ए और बी पर पंक्ति-वार प्रकार करता है (और इसे V1 और V2 पर पुनर्नामित करता है)।

replace_index <- function(dat){ 
    x <- as.data.frame(t(sapply(seq_len(nrow(dat)), 
    function(i)sort(unlist(dat[i, 1:2]))))) 
    names(x) <- paste("V", seq_len(ncol(x)), sep="") 
    data.frame(x, dat[, -(1:2), drop=FALSE]) 
} 

replace_index(df1) 

    V1 V2 C D E F G 
1 1 2 a a a a a 
2 2 3 b b b c c 
3 1 4 e e f f e 

इसका मतलब है आप डेटा गठबंधन करने के लिए एक सीधी-सपाट merge उपयोग कर सकते हैं।

merge(replace_index(df1), replace_index(df2), all.y=TRUE) 

    V1 V2 C D E F G Z 
1 1 2 a a a a a g 
2 1 2 a a a a a h 
3 1 4 e e f f e j 
4 3 4 <NA> <NA> <NA> <NA> <NA> i 
1

यह थोड़ा भद्दा है, और कुछ संभावित टकराव और व्यवस्था संबंधी समस्याएं हो सकती लेकिन

df1a <- df1; df1a$A <- df1$B; df1a$B <- df1$A #reverse A and B 
merge(df2, rbind(df1,df1a), by.x=c("X","Y"), by.y=c("A","B"), all.x=TRUE) 

निर्माण करने के लिए

X Y Z C D E F G 
1 1 2 g a a a a a 
2 1 4 j e e f f e 
3 2 1 h a a a a a 
4 3 4 i <NA> <NA> <NA> <NA> <NA> 
1

एक दृष्टिकोण एक id कुंजी बनाने के लिए किया जाएगा अपने उदाहरण के साथ काम करता मिलान करने के लिए ऑर्डर इनवेरिएंट है।

# create id key to match 
require(plyr) 
df1 = adply(df1, 1, transform, id = paste(min(A, B), "-", max(A, B))) 
df2 = adply(df2, 1, transform, id = paste(min(X, Y), "-", max(X, Y))) 

# combine data frames using `match` 
cbind(df2, df1[match(df2$id, df1$id),3:7]) 

यह आउटपुट

X Y Z id C D E F G 
1 1 2 g 1 - 2 a a a a a 
1.1 2 1 h 1 - 2 a a a a a 
NA 3 4 i 3 - 4 <NA> <NA> <NA> <NA> <NA> 
3 1 4 j 1 - 4 e e f f e 
0

पैदा करता है तुम भी टेबल दोनों तरीकों (X == A और Y == B, तो X == B और Y == A) और उन्हें rbind शामिल हो सकते हैं। यह डुप्लिकेट जोड़े उत्पन्न करेगा जहां एक तरह से एक मैच मिला और दूसरा NA उत्पन्न हुआ, इसलिए आप प्रत्येक एक्स-वाई संयोजन के लिए केवल एक पंक्ति को स्लाइस करके डुप्लिकेट को कम कर देंगे, यदि कोई मौजूद है तो NA के बिना।

library(dplyr) 
m <- left_join(df2,df1,by = c("X" = "A","Y" = "B")) 
n <- left_join(df2,df1,by = c("Y" = "A","X" = "B")) 

rbind(m,n) %>% 
    group_by(X,Y) %>% 
    arrange(C,D,E,F,G) %>% # sort to put NA rows on bottom of pairs 
    slice(1) # take top row from combination 

का उत्पादन:

Source: local data frame [4 x 8] 
Groups: X, Y 

    X Y Z C D E F G 
1 1 2 g a a a a a 
2 1 4 j e e f f e 
3 2 1 h a a a a a 
4 3 4 i NA NA NA NA NA 
0

यहाँ vectorized pmin() और pmax() कार्यों का उपयोग कर प्राप्त करने के लिए दोनों data.frames के आधार आर में एक और संभव समाधान यह समाधान cbind() नई कुंजी कॉलम (K1 और K2) है कुंजी कॉलम का कैनोलिक ऑर्डर, और उन पर विलय:

merge(cbind(df2,K1=pmin(df2$X,df2$Y),K2=pmax(df2$X,df2$Y)),cbind(df1,K1=pmin(df1$A,df1$B),K2=pmax(df1$A,df1$B)),all.x=T)[,-c(1:2,6:7)]; 
## X Y Z C D E F G 
## 1 1 2 g a a a a a 
## 2 2 1 h a a a a a 
## 3 1 4 j e e f f e 
## 4 3 4 i <NA> <NA> <NA> <NA> <NA> 

ध्यान दें कि pmin() और pmax() का उपयोग केवल इस समस्या के लिए संभव है क्योंकि आपके पास केवल दो कुंजी कॉलम हैं; यदि आपके पास और अधिक था, तो आपको विलय के लिए कैननिकल कुंजी ऑर्डर प्राप्त करने के लिए किसी प्रकार का लागू + सॉर्ट समाधान का उपयोग करना होगा, जो कि एंड्रॉइड अपने सहायक फ़ंक्शन में करता है, जो कि किसी भी कुंजी कॉलम के लिए काम करेगा, लेकिन कम प्रदर्शनकारी होगा।

संबंधित मुद्दे