आर में असंगत प्रारूप के डेटा की सफाई?


16

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

लेकिन अभी भी कुछ प्रकार के डेटा हैं जिन्हें मुझे कुशलता से संभालने में परेशानी होती है। उदाहरण के लिए:

> d <- data.frame(subject = c(1,2,3,4,5,6,7,8,9,10,11),
+   hours.per.day = c("1", "2 hours", "2 hr", "2hr", "3 hrs", "1-2", "15 min", "30 mins", "a few hours", "1 hr 30 min", "1 hr/week"))
> d
   subject hours.per.day
1        1             1
2        2       2 hours
3        3          2 hr
4        4           2hr
5        5         3 hrs
6        6           1-2
7        7        15 min
8        8       30 mins
9        9   a few hours
10      10   1 hr 30 min
11      11     1 hr/week

hours.per.dayएक निश्चित गतिविधि पर बिताए जाने वाले दिन प्रति घंटे की औसत संख्या होने का मतलब है, लेकिन हमारे पास वही है जो इस विषय ने लिखा है। मान लीजिए कि मैं अस्पष्ट प्रतिक्रियाओं के साथ क्या करना है, इस पर कुछ निर्णय लेता हूं, और मैं hours.per.day2इस प्रकार के परिवर्तनशील चर चाहता हूं ।

   subject hours.per.day hours.per.day2
1        1             1      1.0000000
2        2       2 hours      2.0000000
3        3          2 hr      2.0000000
4        4           2hr      2.0000000
5        5         3 hrs      3.0000000
6        6           1-2      1.5000000
7        7        15 min      0.2500000
8        8       30 mins      0.5000000
9        9   a few hours      3.0000000
10      10   1 hr 30 min      1.5000000
11      11     1 hr/week      0.1428571

यह मानते हुए कि मामलों की संख्या काफी बड़ी है (1000 का कहना है) और यह जानते हुए कि विषय कुछ भी लिखने के लिए स्वतंत्र थे जो उन्हें पसंद थे, यह दृष्टिकोण करने का सबसे अच्छा तरीका क्या है?

जवाबों:


13

मैं gsub () का उपयोग उन स्ट्रिंग्स की पहचान करने के लिए करूँगा जो मुझे पता है और फिर शायद बाकी को हाथ से करते हैं।

test <- c("15min", "15 min", "Maybe a few hours", 
          "4hr", "4hour", "3.5hr", "3-10", "3-10")
new_var <- rep(NA, length(test))

my_sub <- function(regex, new_var, test){
    t2 <- gsub(regex, "\\1", test)
    identified_vars <- which(test != t2)
    new_var[identified_vars] <- as.double(t2[identified_vars])
    return(new_var)    
}

new_var <- my_sub("([0-9]+)[ ]*min", new_var, test)
new_var <- my_sub("([0-9]+)[ ]*(hour|hr)[s]{0,1}", new_var, test)

जिन कामों के लिए आपको हाथ से बदलने की जरूरत है, उनके साथ काम करने के लिए मैं कुछ इस तरह का सुझाव देता हूं:

# Which have we not found
by.hand <- which(is.na(new_var))

# View the unique ones not found
unique(test[by.hand])
# Create a list with the ones
my_interpretation <- list("3-10"= 5, "Maybe a few hours"=3)
for(key_string in names(my_interpretation)){
    new_var[test == key_string] <- unlist(my_interpretation[key_string])
}

यह देता है:

> new_var
[1] 15.0 15.0  3.0  4.0  4.0  3.5  5.0  5.0

रेगेक्स थोड़ा मुश्किल हो सकता है, हर बार मैं रेगेक्स के साथ कुछ भी कर रहा हूं मैं कुछ सरल परीक्षण चलाता हूं। मैनुअल के लिए Se? Regex। यहाँ कुछ बुनियादी व्यवहार है:

> # Test some regex
> grep("[0-9]", "12")
[1] 1
> grep("[0-9]", "12a")
[1] 1
> grep("[0-9]$", "12a")
integer(0)
> grep("^[0-9]$", "12a")
integer(0)
> grep("^[0-9][0-9]", "12a")
[1] 1
> grep("^[0-9]{1,2}", "12a")
[1] 1
> grep("^[0-9]*", "a")
[1] 1
> grep("^[0-9]+", "a")
integer(0)
> grep("^[0-9]+", "12222a")
[1] 1
> grep("^(yes|no)$", "yes")
[1] 1
> grep("^(yes|no)$", "no")
[1] 1
> grep("^(yes|no)$", "(yes|no)")
integer(0)
> # Test some gsub, the \\1 matches default or the found text within the ()
> gsub("^(yes|maybe) and no$", "\\1", "yes and no")
[1] "yes"

उत्तर के लिए धन्यवाद। मैं नियमित अभिव्यक्तियों से परिचित नहीं हूं इसलिए उनके बारे में सीखना होगा। क्या आप इस बात का संक्षिप्त विवरण देना चाहेंगे कि आप हाथ से बाकी काम कैसे करेंगे? वहाँ की तरह कुछ कर रही की तुलना में एक बेहतर तरीका है new_var[by.hand] <- c(2, 1, ...)के साथ by.handकिया जा रहा है TRUEजिन मामलों में हाथ से किया जाता है के लिए?
mark999

@ mark999: कुछ उदाहरण और एक सुझाव जोड़ा कि कैसे आप हाथ से कर सकते हैं।
मैक्स गॉर्डन

1
किसी भी तरह के डेटा हेरफेर के लिए नियमित अभिव्यक्ति सुपर-महत्वपूर्ण हैं: ओपी के पास डेटा की सफाई, या फ़ाइलों, HTML आदि से डेटा निकालने के लिए, (उचित HTML के लिए, लाइब्रेरी हैं, जैसे XMLकि आप डेटा निकालने में मदद करते हैं, लेकिन यह HTML विकृत होने पर काम नहीं करता है।)
वेन

6

@ मैक्स का सुझाव अच्छा है। ऐसा लगता है कि यदि आप एक एल्गोरिथ्म लिखते हैं जो संख्याओं के साथ-साथ सामान्य समय से जुड़े शब्दों / संक्षिप्ताक्षरों को पहचानता है, तो आपको वहां सबसे अधिक मिलेगा। यह सुंदर कोड नहीं होगा, लेकिन यह काम करेगा और आप समय के साथ इसे सुधार सकते हैं क्योंकि आप समस्या के मामलों में आते हैं।

लेकिन अधिक मजबूत (और शुरू में समय लेने वाली) दृष्टिकोण के लिए, Googling का प्रयास करें "एक प्राकृतिक भाषा समय स्ट्रिंग।" कुछ दिलचस्प निष्कर्ष हैं यह ओपन टाइम एपीआई , एक अच्छा पायथन मॉड्यूल , और स्टैक ओवरफ्लो पर एक जैसे कई जर्मन धागे हैं ।

मूल रूप से, प्राकृतिक भाषा पार्सिंग एक आम समस्या है और आपको आर के अलावा अन्य भाषाओं में समाधान की तलाश करनी चाहिए। आप दूसरी भाषा में ऐसे उपकरण बना सकते हैं, जिन पर आप आर का उपयोग कर सकते हैं, या बहुत कम से कम आप अपने स्वयं के एल्गोरिथ्म के लिए अच्छे विचार प्राप्त कर सकते हैं।


4

इस तरह के कुछ के लिए, अगर यह पर्याप्त रूप से लंबा था, मुझे लगता है कि मैं नियमित अभिव्यक्ति और परिवर्तन नियमों की एक सूची चाहता हूं, और नए मानों को दूसरे कॉलम में ले जाऊंगा (इसलिए आपके पास कच्चे डेटा को फिर से लोड किए बिना दोहरी जांच करने का मौका है) ; आरईआर को तब तक लागू नहीं किया जाएगा जब तक कि सभी डेटा को बदल नहीं दिया जाए या सभी नियम समाप्त न हो जाएं। संभवतः तार्किक मूल्यों की एक सूची रखना सबसे अच्छा है जो इंगित करते हैं कि कौन सी पंक्तियों को अभी तक रूपांतरित नहीं किया गया है।

इस तरह के कुछ नियम निश्चित रूप से स्पष्ट हैं और शायद 80-90% मामलों को संभालेंगे, लेकिन मुद्दा यह है कि हमेशा कुछ ऐसे होंगे जो आपको नहीं पता होंगे (लोग बहुत आविष्कारशील हैं)।

फिर आपको एक ऐसी स्क्रिप्ट की ज़रूरत होती है, जो आपको एक बार में एक-न-बदले-से-सूची-में-स्पष्ट-नियमों के मूल मानों को प्रस्तुत करती है, जो आपको एक नियमित अभिव्यक्ति बनाने का मौका देती है (कहते हैं ) उन मामलों की पहचान करने और उन मामलों के लिए एक नया परिवर्तन देने के लिए जो इसे फिट करते हैं, जो इसे मूल सूची में जोड़ता है और जाँच करने से पहले मूल वेक्टर की नहीं-अभी तक रूपांतरित पंक्तियों पर लागू होता है यदि आपके पास प्रस्तुत करने के लिए कोई भी मामले हैं। ।

किसी मामले को छोड़ने का विकल्प रखना भी उचित हो सकता है (ताकि आप आसानी से आगे बढ़ सकें), ताकि आप अंत तक बहुत ही कठिन मामलों को रोक सकें।

सबसे खराब स्थिति, आप हाथ से कुछ करते हैं।

तब आप अपने द्वारा बनाए गए नियमों की पूरी सूची रख सकते हैं, जब डेटा बढ़ता है या नया, समान डेटा सेट साथ आता है।

मुझे नहीं पता कि यह सबसे अच्छा अभ्यास है। मुझे लगता है कि (कुछ और औपचारिक की आवश्यकता होगी), लेकिन बड़ी मात्रा में ऐसे डेटा को जल्दी से संसाधित करने के मामले में, इसका कुछ मूल्य हो सकता है।


जवाब के लिए धन्यवाद, ग्लेन। यह बहुत आकर्षक लगता है। क्या आप इसे एक बड़े लाभ के रूप में देखते हैं, जो एक बार में प्रस्तुत नहीं किए गए मूल्यों को प्रस्तुत करने के रूप में, उन सभी को प्रदर्शित करने और उस आउटपुट को देखने के विपरीत है? मैंने कभी भी ऐसा कुछ नहीं किया है जैसे चीजों को एक बार में प्रस्तुत किया गया हो।
mark999

1
@ mark999, मुझे लगता है कि एक बार की प्रस्तुति के फायदे और नुकसान दोनों हैं। लाभ सरलता है - अस्पष्ट समय प्रदर्शित करने के लिए बिल्ली () का उपयोग करना, और स्कैन करना () उस समय की अपनी व्याख्या को रिकॉर्ड करना आसान है। नुकसान यह है कि आप बहुत सारी प्रविष्टियों की बड़ी तस्वीर को याद कर सकते हैं जिसे आप regex कोड की एक पंक्ति के साथ ठीक कर सकते हैं। आपको इस बारे में सोचना चाहिए कि आप क्या पाने की उम्मीद कर रहे हैं: यदि आप इस समस्या को हल करना चाहते हैं, तो इसे हाथ से करें। यदि आप R के बारे में अधिक जानना चाहते हैं, तो समाधान को कोड करने का प्रयास करें।
ऐश

उत्तर की कमी के लिए क्षमा करें; मैं ऐश की टिप्पणी से व्यापक रूप से सहमत हूँ
Glen_b -Reinstate Monica

4

आर कुछ शामिल मानक डेटा हेरफेर के लिए काम करता है, जो डेटा सफाई के लिए इस्तेमाल किया जा सकता है अपने में आधार पैकेज ( gsub, transformजैसे, आदि), और साथ ही में विभिन्न तृतीय-पक्ष संकुल, stringr , आकृति बदलें , reshape2 , और plyr । इन पैकेजों और उनके कार्यों के उपयोग के उदाहरण और सर्वोत्तम अभ्यास निम्नलिखित पेपर में वर्णित हैं: http://vita.had.co.nz/papers/tidy-data.pdf

इसके अतिरिक्त, आर कुछ पैकेज विशेष रूप से डेटा सफाई और परिवर्तन पर केंद्रित है :

आर में डेटा की सफाई के लिए एक व्यापक और सुसंगत दृष्टिकोण , जिसमें एडिट्रूल्स और डयूटीरेक्ट पैकेज के उदाहरण और उपयोग के साथ-साथ आर में डेटा सफाई के वर्कफ़्लो ( फ्रेमवर्क ) का विवरण निम्नलिखित पेपर में प्रस्तुत किया गया है, जिसे मैं अत्यधिक अनुशंसा करता हूं: http : : //cran.r-project.org/doc/contrib/de_Jonge+van_der_Loo-Introduction_to_data_cleaning_with_R.pdf

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.