आर

2011-08-19 5 views
14

में चर के फ़ज़ी मिलान के माध्यम से विलय करना मेरे पास दो डेटाफ्रेम (x y) हैं, जहां आईडी student_name, father_name और mother_name हैं। टाइपोग्राफ़िकल त्रुटियों ("एम" के बजाय "एम", यादृच्छिक सफेद रिक्त स्थान इत्यादि), मेरे पास लगभग 60% मान हैं जो संरेखित नहीं हैं, हालांकि मैं डेटा को नजरअंदाज कर सकता हूं और उन्हें देखना चाहिए। क्या किसी भी तरह के गैर-मिलान के स्तर को कम करने का कोई तरीका है ताकि मैन्युअल रूप से संपादन संभवतः कम से कम संभव हो? डेटाफ्रेम के बारे में 700 के अवलोकन हैं।आर

आर सबसे अच्छा होगा। मुझे थोड़ा सा अजगर, और कुछ बुनियादी यूनिक्स उपकरण पता है। अनुलेख मैंने agrep() पर पढ़ा है, लेकिन यह समझ में नहीं आता कि यह वास्तविक डेटासेट पर कैसे काम कर सकता है, खासकर जब मैच एक से अधिक चर से अधिक हो।


अद्यतन (पोस्ट इनाम के लिए डेटा):

Here दो उदाहरण डेटा फ्रेम, sites_a और sites_b हैं। उन्हें संख्यात्मक कॉलम lat और lon के साथ-साथ sitename कॉलम पर मिलान किया जा सकता है। यह जानना उपयोगी होगा कि यह कैसे किया जा सकता है) lat + lon, बी) sitename या सी) दोनों।

आप फ़ाइल को test_sites.R पर स्रोत कर सकते हैं जिसे एक गिस्ट के रूप में पोस्ट किया गया है।

आदर्श रूप में जवाब के साथ

merge(sites_a, sites_b, by = **magic**) 
+0

क्या आप अपने डेटा का एक छोटा सबसेट प्रदान कर सकते हैं (या हमें कुछ नकली डेटा प्रदान कर सकते हैं)? –

+2

@ RomanLuštrik हालांकि यह मूल रूप से मेरा प्रश्न नहीं था, मेरे पास एक समान समस्या थी, कुछ नमूना डेटा बनाया है, और एक उपहार प्रदान किया है। –

+0

@ डेविड ने आपने 'मर्ज करने की कोशिश की है (sites_a, sites_b, by = c ("lon", "lat")) '? आपके मामले में, यदि आप नामों से विलय करना चाहते हैं, तो आपको डेटा दोनों नामों में नाम बनाने में अधिक ऊर्जा निवेश करनी होगी। फ्रेम मैच (शुभकामनाएं, हुह)। उदाहरण के लिए –

उत्तर

6

agrep समारोह (आधार आर का हिस्सा), जो Levenshtein edit distance का उपयोग कर अनुमानित स्ट्रिंग मिलान करता है शायद कोशिश कर रहा लायक है खत्म होगा। यह जानने के बिना कि आपका डेटा कैसा दिखता है, मैं वास्तव में एक समाधान समाधान का सुझाव नहीं दे सकता। लेकिन यह एक सुझाव है ... यह एक अलग सूची में मैचों को रिकॉर्ड करता है (यदि कई समान अच्छे मिलान हैं, तो इन्हें भी रिकॉर्ड किया जाता है)। मान लें कि आपका data.frame df कहा जाता है दो:

l <- vector('list',nrow(df)) 
matches <- list(mother = l,father = l) 
for(i in 1:nrow(df)){ 
    father_id <- with(df,which(student_name[i] == father_name)) 
    if(length(father_id) == 1){ 
    matches[['father']][[i]] <- father_id 
    } else { 
    old_father_id <- NULL 
    ## try to find the total                                 
    for(m in 10:1){ ## m is the maximum distance                            
     father_id <- with(df,agrep(student_name[i],father_name,max.dist = m)) 
     if(length(father_id) == 1 || m == 1){ 
     ## if we find a unique match or if we are in our last round, then stop                    
     matches[['father']][[i]] <- father_id 
     break 
     } else if(length(father_id) == 0 && length(old_father_id) > 0) { 
     ## if we can't do better than multiple matches, then record them anyway                    
     matches[['father']][[i]] <- old_father_id 
     break 
     } else if(length(father_id) == 0 && length(old_father_id) == 0) { 
     ## if the nearest match is more than 10 different from the current pattern, then stop                 
     break 
     } 
    } 
    } 
} 

कोड mother_name के लिए मूल रूप से ही होगा। आप उन्हें एक लूप में भी एक साथ रख सकते हैं, लेकिन यह उदाहरण सिर्फ चित्रण के उद्देश्य के लिए है।

+0

धन्यवाद, nullglob। क्या आप डेटाफ्रेम (एक्स, वाई) और चर (student_name, आदि) वाक्यविन्यास का उपयोग करके समझा सकते हैं। – user702432

+0

क्षमा करें @ user702432, मैंने आपके प्रश्न को सावधानीपूर्वक पर्याप्त नहीं पढ़ा। आप और पहले से ही 'agrep' मिला है। मैंने इस बारे में एक सुझाव जोड़ा है कि आप इसे अपने डेटा के साथ कैसे इस्तेमाल कर सकते हैं। फ्रेम – nullglob

5

यह आम स्तंभ नामों की एक सूची ले जाता है, उन सभी संयुक्त स्तंभों की agrep के आधार पर मैच, और फिर इसे एनए के साथ कॉलम नहीं हैं में भरने के मेल नहीं खाने वाले अभिलेखों संलग्न कर देता है, तो all.x या all.y सही बराबर होती है। merge के विपरीत, प्रत्येक डेटा फ्रेम में मिलान करने के लिए कॉलम नाम समान होने की आवश्यकता है। चुनौतीपूर्ण मैचों से बचने के लिए चुनौती agrep विकल्पों को सही ढंग से सेट कर रही है।

agrepMerge <- function(df1, df2, by, all.x = FALSE, all.y = FALSE, 
    ignore.case = FALSE, value = FALSE, max.distance = 0.1, useBytes = FALSE) { 

    df1$index <- apply(df1[,by, drop = FALSE], 1, paste, sep = "", collapse = "") 
    df2$index <- apply(df2[,by, drop = FALSE], 1, paste, sep = "", collapse = "") 

    matches <- lapply(seq_along(df1$index), function(i, ...) { 
     agrep(df1$index[i], df2$index, ignore.case = ignore.case, value = value, 
      max.distance = max.distance, useBytes = useBytes) 
    }) 

    df1_match <- rep(1:nrow(df1), sapply(matches, length)) 
    df2_match <- unlist(matches) 

    df1_hits <- df1[df1_match,] 
    df2_hits <- df2[df2_match,] 

    df1_miss <- df1[setdiff(seq_along(df1$index), df1_match),] 
    df2_miss <- df2[setdiff(seq_along(df2$index), df2_match),] 

    remove_cols <- colnames(df2_hits) %in% colnames(df1_hits) 

    df_out <- cbind(df1_hits, df2_hits[,!remove_cols]) 

    if(all.x) { 
     missing_cols <- setdiff(colnames(df_out), colnames(df1_miss)) 
     df1_miss[missing_cols] <- NA 
     df_out <- rbind(df_out, df1_miss) 
    } 
    if(all.x) { 
     missing_cols <- setdiff(colnames(df_out), colnames(df2_miss)) 
     df2_miss[missing_cols] <- NA 
     df_out <- rbind(df_out, df2_miss) 
    } 
    df_out[,setdiff(colnames(df_out), "index")] 
} 
+0

इसे यहां एक गिस्ट में रखें: https://gist.github.com/enricoferrero/0e41549d437aeda4d5f2f95116316c00 – enricoferrero