आर

2012-05-16 8 views
6

में आंशिक मैच के साथ डेटा को मर्ज मैं दो डेटासेटआर

datf1 <- data.frame (name = c("regular", "kklmin", "notSo", "Jijoh", 
"Kish", "Lissp", "Kcn", "CCCa"), 
number1 = c(1, 8, 9, 2, 18, 25, 33, 8)) 
#----------- 
    name number1 
1 regular  1 
2 kklmin  8 
3 notSo  9 
4 Jijoh  2 
5 Kish  18 
6 Lissp  25 
7  Kcn  33 
8 CCCa  8 

datf2 <- data.frame (name = c("reGulr", "ntSo", "Jijoh", "sean", "LiSsp", 
"KcN", "CaPN"), 
    number2 = c(2, 8, 12, 13, 20, 18, 13)) 
#------------- 
    name number2 
1 reGulr  2 
2 ntSo  8 
3 Jijoh  12 
4 sean  13 
5 LiSsp  20 
6 KcN  18 
7 CaPN  13 

है मैं नाम कॉलम के आधार पर उन्हें मर्ज करना चाहते हैं, आंशिक मैच तथापि साथ (बड़े डेटा में वर्तनी त्रुटियों विलय की स्थापना की और भी करने के लिए बाधा से बचने के लिए अनुमति दी है इस तरह के वर्तनी त्रुटियों का पता लगाने) और उदाहरण के लिए

(1) अगर लगातार चार पत्र (पत्रों की संख्या रहे हैं सब करता है, तो कम से कम 4) किसी भी स्थिति में - मेल खाते हैं कि

ABBCD = BBCDK = aBBCD = ramABBBCD = ABB 

(2) प्रकरण ठीक है सेन मैच में साइटिविटी बंद है जैसे ABBCD = aBbCd

(3) नए डेटासेट में दोनों नाम (डेटाफ 1 और डेटाएफ 2 से नाम) होंगे। तो यह पत्र हम पता लगा सकते हैं कि मैच सही है (कितना अक्षर मिलान करता है के साथ एक अलग कॉलम हो सकता है)

क्या ऐसा विलय संभव है?

संपादन:

datf1 <- data.frame (name = c("xxregular", "kklmin", "notSo", "Jijoh", 
      "Kish", "Lissp", "Kcn", "CCCa"), 
        number1 = c(1, 8, 9, 2, 18, 25, 33, 8)) 
datf2 <- data.frame (name = c("reGulr", "ntSo", "Jijoh", "sean", 
      "LiSsp", "KcN", "CaPN"), 
        number2 = c(2, 8, 12, 13, 20, 18, 13)) 


uglyMerge(datf1, datf2) 
     name1 name2 number1 number2 matches 
1 xxregular <NA>  1  NA  0 
2  kklmin <NA>  8  NA  0 
3  notSo <NA>  9  NA  0 
4  Jijoh Jijoh  2  12  5 
5  Kish <NA>  18  NA  0 
6  Lissp LiSsp  25  20  5 
7  Kcn KcN  33  18  3 
8  CCCa <NA>  8  NA  0 
9  <NA> reGulr  NA  2  0 
10  <NA> ntSo  NA  8  0 
11  <NA> sean  NA  13  0 
12  <NA> CaPN  NA  13  0 
+0

कुछ स्वरूपण को ठीक करने का प्रयास किया। मैं देखता हूं कि आपने "uglyMerge" की एक प्रति जोड़ा है जो @sgibb की प्रतिक्रिया से प्रतीत होता है। 'Rexulr' के साथ 'xxregular' के मिलान की कमी आपके लिए स्पष्ट हो सकती है, लेकिन आपको इसे समझाने की आवश्यकता हो सकती है, क्योंकि ऐसा लगता है कि यह आपके विनिर्देशों को पूरा करता है –

उत्तर

7

हो सकता है कि वहाँ एक सरल उपाय है, लेकिन मैं किसी भी नहीं मिल रहा।
आईएमएचओ आपको इस तरह के विलय को अपने लिए लागू करना होगा।
कृपया एक बदसूरत उदाहरण के लिए नीचे दिया (वहाँ सुधार के लिए अंतरिक्ष के एक बहुत कुछ है):

uglyMerge <- function(df1, df2) { 

    ## lower all strings to allow case-insensitive comparison 
    lowerNames1 <- tolower(df1[, 1]); 
    lowerNames2 <- tolower(df2[, 1]); 

    ## split strings into single characters 
    names1 <- strsplit(lowerNames1, ""); 
    names2 <- strsplit(lowerNames2, ""); 

    ## create the final dataframe 
    mergedDf <- data.frame(name1=as.character(df1[,1]), name2=NA, 
         number1=df1[,2], number2=NA, matches=0, 
         stringsAsFactors=FALSE); 

    ## store names of dataframe2 (to remember which strings have no match) 
    toMerge <- df2[, 1]; 

    for (i in seq(along=names1)) { 
     for (j in seq(along=names2)) { 
      ## set minimal match to 4 or to string length 
      minMatch <- min(4, length(names2[[j]])); 

      ## find single matches 
      matches <- names1[[i]] %in% names2[[j]]; 

      ## look for consecutive matches 
      r <- rle(matches); 

      ## any matches found? 
      if (any(r$values)) { 
       ## find max consecutive match 
       possibleMatch <- r$value == TRUE; 
       maxPos <- which(which.max(r$length[possibleMatch]) & possibleMatch)[1]; 

       ## store max conscutive match length 
       maxMatch <- r$length[maxPos]; 

       ## to remove FALSE-POSITIVES (e.g. CCC and kcn) find 
       ## largest substring 
       start <- sum(r$length[0:(maxPos-1)]) + 1; 
       stop <- start + r$length[maxPos] - 1; 
       maxSubStr <- substr(lowerNames1[i], start, stop); 

       ## all matching criteria fulfilled 
       isConsecutiveMatch <- maxMatch >= minMatch && 
            grepl(pattern=maxSubStr, x=lowerNames2[j], fixed=TRUE) && 
            nchar(maxSubStr) > 0; 

       if (isConsecutiveMatch) { 
        ## merging 
        mergedDf[i, "matches"] <- maxMatch 
        mergedDf[i, "name2"] <- as.character(df2[j, 1]); 
        mergedDf[i, "number2"] <- df2[j, 2]; 

        ## don't append this row to mergedDf because already merged 
        toMerge[j] <- NA; 

        ## stop inner for loop here to avoid possible second match 
        break; 
       } 
      } 
     } 
    } 

    ## append not matched rows to mergedDf 
    toMerge <- which(df2[, 1] == toMerge); 
    df2 <- data.frame(name1=NA, name2=as.character(df2[toMerge, 1]), 
        number1=NA, number2=df2[toMerge, 2], matches=0, 
        stringsAsFactors=FALSE); 
    mergedDf <- rbind(mergedDf, df2); 

    return (mergedDf); 
} 

आउटपुट:

> uglyMerge(datf1, datf2) 
    name1 name2 number1 number2 matches 
1 xxregular reGulr  1  2  5 
2  kklmin <NA>  8  NA  0 
3  notSo <NA>  9  NA  0 
4  Jijoh Jijoh  2  12  5 
5  Kish <NA>  18  NA  0 
6  Lissp LiSsp  25  20  5 
7  Kcn KcN  33  18  3 
8  CCCa <NA>  8  NA  0 
9  <NA> ntSo  NA  8  0 
10  <NA> sean  NA  13  0 
11  <NA> CaPN  NA  13  0 
+0

महान समाधान के लिए धन्यवाद। यह मेरे द्वारा प्रदान किए गए उदाहरण के साथ ठीक काम करता है। लेकिन मुझे आगे बढ़ने की आवश्यकता हो सकती है क्योंकि ऐसा लगता है कि यह काम नहीं करता है अगर यह लगातार चार अक्षरों वाला नहीं है, तो बस मेरे संपादन देखें जहां मैंने नियमित रूप से अतिरिक्त xxx जोड़ा, मिलान न करें। फिर भी, यह मुझे बहुत अच्छी शुरुआत प्रदान करेगा, धन्यवाद !! – jon

+0

@hijo क्षमा करें मेरी सबस्ट्रिंग गणना में कुछ बग थे। कृपया मेरे संशोधित संस्करण का उपयोग करें। – sgibb

+0

स्ट्रिंग मिलान करने के लिए कुछ [संपादन दूरी] (http://en.wikipedia.org/wiki/Levenshtein_distance) का उपयोग करने के लिए आपके लिए मूल्य भी हो सकता है। इसमें [कार्यान्वयन] है (http://stackoverflow.com/questions/3182091/fast-levenshtein-distance-in-r) आर में। –

3

agrep आप शुरू हो जाएगा।

कुछ की तरह:

lapply(tolower(datf1$name), function(x) agrep(x, tolower(datf2$name))) 

तो आप जब तक आप मिलान की उचित राशि प्राप्त max.distance पैरामीटर समायोजित कर सकते हैं। फिर मर्ज करें हालांकि आपको पसंद है।