R में गुम मान (NA) को कैसे बदलें: na.omit & na.rm
⚡ स्मार्ट सारांश
R में गुमशुदा मानों को बदलना (Replace Missing Values in R) पाठ्यक्रम में NA मानों का पता लगाना, na.omit() का उपयोग करके अपूर्ण पंक्तियों को हटाना और mutate() के माध्यम से उन्हें माध्य या माध्यिका से भरना शामिल है। इस पाठ्यक्रम में टाइटैनिक डेटासेट का उपयोग किया गया है, जिसमें आयु और किराया दोनों में गुमशुदा अवलोकन हैं।
R में मिसिंग वैल्यू क्या होती हैं?
किसी कॉलम में कोई मान दर्ज न होने पर या संख्या के स्थान पर गैर-संख्यात्मक प्लेसहोल्डर होने पर लुप्त मान दिखाई देते हैं। किसी भी गणना से पहले इन्हें हटाना या बदलना आवश्यक है, क्योंकि R के अधिकांश फ़ंक्शन इनके मौजूद होते ही NA मान लौटाते हैं।
यह ट्यूटोरियल दिखाता है कि डेटा विश्लेषण के लिए टाइडीवर्स इकोसिस्टम का हिस्सा, डीप्लायर लाइब्रेरी का उपयोग करके गुम मानों को कैसे संभाला जाए।
पहला कदम हमेशा यह पता लगाना होता है कि कितने मान गायब हैं और कहाँ हैं।
R में लुप्त मानों का पता कैसे लगाएं और उनकी गणना कैसे करें
लुप्त मानों के बारे में निर्णय लेने से पहले, आपको यह जानना आवश्यक है कि वे कितने हैं और कहाँ स्थित हैं। R चार जाँच विकल्प प्रदान करता है, जिनमें एक हाँ या ना में उत्तर से लेकर प्रत्येक कॉलम के लिए पूर्ण गणना तक शामिल हैं।
# 1. Is there any NA at all? anyNA(df_titanic) # 2. How many in total? sum(is.na(df_titanic)) # 3. How many per column, the most useful view colSums(is.na(df_titanic)) # 4. Percentage missing per column round(colMeans(is.na(df_titanic)) * 100, 1)
व्यवहार में colSums() फ़ंक्शन का उपयोग करना सबसे अच्छा है। यह प्रत्येक कॉलम के लिए एक मान वाला एक नामयुक्त वेक्टर लौटाता है, जिससे तुरंत पता चल जाता है कि किसी वेरिएबल में कुछ मान गायब हैं या वह लगभग खाली है।
पूरी पंक्तियों की गिनती करना। complete.cases() उन पंक्तियों के लिए TRUE लौटाता है जिनमें कहीं भी कोई लुप्त मान नहीं होता है, जो आपको पहले से ही बता देता है कि na.omit() कितना डेटा हटा देगा:
sum(complete.cases(df_titanic)) # rows that would survive sum(!complete.cases(df_titanic)) # rows that would be dropped
प्लेसहोल्डर्स के बारे में एक चेतावनी। R केवल NA को ही पहचानता है। डेटासेट अक्सर गुमशुदा मानों को खाली स्ट्रिंग, स्पेस, “N/A”, “-”, या -99 या 999 जैसे सेंटिनल नंबर के रूप में एन्कोड करते हैं। ये सभी ऊपर दिए गए सभी चेक को बिना किसी पहचान के पास कर लेते हैं। इन्हें आयात करते समय परिवर्तित करें ताकि बाकी वर्कफ़्लो सुचारू रूप से काम करे:
df <- read.csv(PATH, na.strings = c("", " ", "NA", "N/A", "-", "-99"))
आयात करने के बाद हमेशा प्रत्येक संख्यात्मक कॉलम की सीमा की जांच करें। -99 की आयु या 9999 का किराया, एक सामान्य NA मान से कहीं अधिक खतरनाक है, क्योंकि इसके बारे में कोई भी फ़ंक्शन आपको चेतावनी नहीं देगा।
लुप्त डेटा के प्रकार: MCAR, MAR और MNAR
किसी मान के अनुपलब्ध होने का कारण यह निर्धारित करता है कि उसका अनुमान लगाना सुरक्षित है या नहीं। सांख्यिकीविद तीन तंत्रों को पहचानते हैं।
- MCAR, पूरी तरह से संयोगवश गायब हो गया। लापता होने की संभावना किसी भी चीज से संबंधित नहीं है, चाहे वह देखी गई हो या नहीं, उदाहरण के लिए एक सेंसर जो यादृच्छिक क्षणों में विफल हो जाता है।ping इन पंक्तियों में डेटा भरने से कोई पूर्वाग्रह उत्पन्न नहीं होता, केवल सटीकता में कमी आती है।
- एमएआर, यादृच्छिक रूप से गायब। संभावना अन्य प्रेक्षित चरों पर निर्भर करती है, न कि स्वयं लुप्त मान पर। यदि वृद्ध यात्रियों की आयु दर्ज होने की संभावना कम है, तो अन्य स्तंभों को देखते हुए आयु MAR है। उन स्तंभों का उपयोग करने वाला इम्पुटेशन इसे अच्छी तरह से संभालता है।
- एमएनएआर, लापता होना यादृच्छिक नहीं है। संभावना स्वयं अनदेखे मूल्य पर निर्भर करती है, उदाहरण के लिए उच्च आय वाले लोग अपनी आय बताने से इनकार करते हैं। कोई भी अनुमान विधि केवल डेटा के आधार पर इसे ठीक नहीं कर सकती, और गुम डेटा में ही महत्वपूर्ण जानकारी छिपी होती है जिसे चिह्नित कॉलम में दर्ज करना आवश्यक है।
इस ट्यूटोरियल में प्रयुक्त माध्य इम्पुटेशन, केवल MCAR और सरल MAR के अंतर्गत ही उचित है। फिर भी, इसकी एक ज्ञात कमी है: प्रत्येक रिक्त स्थान को एक ही संख्या से भरने से कॉलम का विचरण कम हो जाता है और अन्य सभी कारकों के साथ उसका सहसंबंध कमजोर हो जाता है। गंभीर कार्य के लिए, MICE पैकेज जैसे मॉडल-आधारित विधि का उपयोग करें, और हमेशा एक फ़्लैग कॉलम रखें जो यह दर्शाता हो कि किन मानों को इम्पुट किया गया है।
उत्परिवर्तित ()
mutate() है दुत्कार यह एक क्रिया है जो एक नया चर बनाती है या मौजूदा चर को ओवरराइट करती है, जिससे यह किसी कॉलम की साफ-सुथरी प्रतिलिपि बनाने के लिए एक स्वाभाविक उपकरण बन जाता है।
हम दो भागों में आगे बढ़ेंगे। हम सीखेंगे कि कैसे:
- डेटा फ़्रेम से अनुपलब्ध मानों को बाहर निकालें
- माध्य और मध्यिका के साथ लुप्त मानों को आरोपित करें
क्रिया mutate() का उपयोग करना बहुत आसान है। हम इस सिंटैक्स का पालन करके एक नया चर बना सकते हैं:
mutate(df, name_variable_1 = condition, ...) arguments: -df: Data frame used to create a new variable -name_variable_1: Name and the formula to create the new variable -...: No limit constraint. Possibility to create more than one variable inside mutate()
अनुपलब्ध मानों (NA) को शामिल न करें
na.omit() एक बेस R फ़ंक्शन है, न कि dplyr वर्ब, लेकिन यह फिर भी सुचारू रूप से काम करता है। यह उन सभी पंक्तियों को हटा देता है जिनमें कम से कम एक NA मान होता है। यह सबसे तेज़ विकल्प है, लेकिन शायद ही कभी सबसे अच्छा विकल्प होता है, क्योंकि एक भी लुप्त मान पूरे अवलोकन को खारिज कर देता है।
लापता अवलोकनों की समस्या से निपटने के लिए, हम टाइटैनिक डेटासेट का उपयोग करेंगे। इस डेटासेट में, हमें त्रासदी के दौरान विमान में सवार यात्रियों की जानकारी तक पहुँच प्राप्त है। इस डेटासेट में कई NA हैं जिनका ध्यान रखना आवश्यक है।
इंटरनेट से CSV फ़ाइल लोड करें, फिर उन कॉलमों की सूची बनाएं जिनमें NA मान मौजूद है:
PATH <- "https://raw.githubusercontent.com/guru99-edu/R-Programming/master/test.csv" df_titanic <- read.csv(PATH, sep = ",") # Return the column names containing missing observations list_na <- colnames(df_titanic)[ apply(df_titanic, 2, anyNA) ] list_na
आउटपुट:
## [1] "age" "fare"
यहाँ,
colnames(df_titanic)[apply(df_titanic, 2, anyNA)]
यह उन कॉलमों के नाम लौटाता है जिनमें कम से कम एक लुप्त मान मौजूद है।
आयु और किराया स्तंभों में मान लुप्त हैं।
हम उन्हें na.omit() के साथ हटा सकते हैं।
library(dplyr) # Exclude the missing observations df_titanic_drop <-df_titanic %>% na.omit() dim(df_titanic_drop)
आउटपुट:
## [1] 1045 13
नए डेटासेट में 1045 पंक्तियाँ हैं, जबकि मूल डेटासेट में 1309 पंक्तियाँ थीं।
माध्य और माध्यिका का उपयोग करके लुप्त डेटा को भरें।
आप माध्य या माध्यिका का उपयोग करके लुप्त मानों को भर सकते हैं। एक अच्छा तरीका यह है कि माध्य और माध्यिका के लिए दो अलग-अलग चर बनाएँ। एक बार बन जाने के बाद, हम लुप्त मानों को नए बनाए गए चरों से बदल सकते हैं।
हम NA वाले कॉलम का माध्य निकालने के लिए apply विधि का उपयोग करेंगे। आइए एक उदाहरण देखें
चरण 1) ट्यूटोरियल में पहले हमने कॉलम के नाम को लिस्ट_na नामक सूची में गुम मानों के साथ संग्रहीत किया था। हम इस सूची का उपयोग करेंगे
चरण 2) na.rm = TRUE आर्गुमेंट का उपयोग करके माध्य की गणना करें। यह आर्गुमेंट अनिवार्य है क्योंकि कॉलम में अनुपलब्ध डेटा है, और यह R को उन्हें अनदेखा करने के लिए कहता है।
# Create mean average_missing <- apply(df_titanic[,colnames(df_titanic) %in% list_na], 2, mean, na.rm = TRUE) average_missing
Code स्पष्टीकरण:
हम apply विधि में 4 तर्क पास करते हैं।
- df: df_titanic[,colnames(df_titanic) %in% list_na]. यह कोड list_na ऑब्जेक्ट से कॉलम का नाम लौटाएगा (यानी “आयु” और “किराया”)
- 2: कॉलम पर फ़ंक्शन की गणना करें
- माध्य: माध्य की गणना करें
- na.rm = सत्य: लुप्त मानों को अनदेखा करें
आउटपुट:
## age fare ## 29.88113 33.29548
हमने लापता प्रेक्षणों वाले स्तंभों का माध्य सफलतापूर्वक बनाया है। इन दो मानों का उपयोग लापता प्रेक्षणों को प्रतिस्थापित करने के लिए किया जाएगा।
चरण 3) NA मान बदलें
dplyr लाइब्रेरी से क्रिया mutate एक नया चर बनाने में उपयोगी है। हम मूल कॉलम को बदलना नहीं चाहते हैं ताकि हम NA के बिना एक नया चर बना सकें। mutate का उपयोग करना आसान है, हम बस एक चर नाम चुनते हैं और परिभाषित करते हैं कि इस चर को कैसे बनाया जाए। यहाँ पूरा कोड है
# Create a new variable with the mean and median df_titanic_replace <- df_titanic %>% mutate(replace_mean_age = ifelse(is.na(age), average_missing[1], age), replace_mean_fare = ifelse(is.na(fare), average_missing[2], fare))
Code स्पष्टीकरण:
हम दो चर बनाते हैं, replace_mean_age और replace_mean_fare इस प्रकार:
- replace_mean_age = ifelse(is.na(आयु), औसत_अनुपलब्ध[1], आयु)
- replace_mean_fare = ifelse(is.na(किराया), औसत_लापता[2],किराया)
यदि कॉलम आयु में कोई मान गायब है, तो उसे average_missing (आयु का माध्य) के पहले तत्व से बदलें, अन्यथा मूल मान रखें। किराया के लिए भी यही तर्क लागू होता है
sum(is.na(df_titanic_replace$age))
आउटपुट:
## [1] 263
प्रतिस्थापन के बाद, नए कॉलम में कोई भी लुप्त मान नहीं है:
sum(is.na(df_titanic_replace$replace_mean_age))
आउटपुट:
## [1] 0
मूल आयु कॉलम में 263 लुप्त मान थे, जबकि नए replace_mean_age कॉलम ने उन सभी को औसत आयु से भर दिया है।
चरण 4) हम लुप्त प्रेक्षणों को माध्यिका से भी प्रतिस्थापित कर सकते हैं।
median_missing <- apply(df_titanic[,colnames(df_titanic) %in% list_na], 2, median, na.rm = TRUE) df_titanic_replace <- df_titanic %>% mutate(replace_median_age = ifelse(is.na(age), median_missing[1], age), replace_median_fare = ifelse(is.na(fare), median_missing[2], fare)) head(df_titanic_replace)
आउटपुट:
चरण 5) एक विस्तृत डेटासेट पर चरण-दर-चरण विधि थकाऊ हो जाती है। sapply() पूरी प्रक्रिया को एक ही वाक्य में समेट देता है, हालांकि इसमें अनुमानित मान कभी नहीं देखे जा सकते।
sapply एक नहीं बनाता है डेटा ढांचा, इसलिए हम डेटा फ़्रेम ऑब्जेक्ट बनाने के लिए sapply() फ़ंक्शन को data.frame() के भीतर लपेट सकते हैं।
# Quick code to replace missing values with the mean df_titanic_impute_mean <- data.frame( sapply( df_titanic, function(x) ifelse(is.na(x), mean(x, na.rm = TRUE), x)))
replace_na() और across() के साथ आधुनिक इम्पुटेशन
ऊपर बताए गए apply() और sapply() तरीके अभी भी काम करते हैं, लेकिन tidyr और dplyr अब उन्हीं ऑपरेशनों को अधिक सुरक्षित और अधिक पठनीय तरीके से व्यक्त करते हैं।
निश्चित मानों के लिए replace_na() का प्रयोग करें। tidyr::replace_na() कॉलम और उनके प्रतिस्थापनों की एक नामित सूची लेता है:
library(tidyr) df_titanic %>% replace_na(list(age = 29.88, fare = 33.30))
प्रत्येक संख्यात्मक कॉलम के लिए across() फ़ंक्शन का उपयोग करें। यह sapply() के एक लाइन वाले कोड का सीधा, टाइप-सेफ विकल्प है, और sapply() के विपरीत, यह कभी भी कैरेक्टर या फैक्टर कॉलम को नहीं छूता है:
library(dplyr) # Mean-impute every numeric column df_titanic %>% mutate(across(where(is.numeric), ~ ifelse(is.na(.x), mean(.x, na.rm = TRUE), .x))) # Median-impute instead df_titanic %>% mutate(across(where(is.numeric), ~ ifelse(is.na(.x), median(.x, na.rm = TRUE), .x)))
⚠️ sapply() शॉर्टकट का उपयोग करना जोखिम भरा क्यों है: एक पंक्ति वाला sapply() उदाहरण चलता है प्रत्येक कॉलम, जिनमें कैरेक्टर और फैक्टर कॉलम भी शामिल हैं। उन पर mean() फ़ंक्शन चलाने पर NA मान और एक चेतावनी मिलती है, और sapply() फ़ंक्शन पूरे परिणाम को कैरेक्टर में बदल देता है। ऊपर दिया गया across(where(is.numeric), …) संस्करण इस समस्या से पूरी तरह बचता है।
फ़ॉलबैक कॉलम के लिए coalesce() का उपयोग करें। जब दूसरा कॉलम लुप्त मान प्रदान कर सकता है, तो coalesce() अपने सभी तर्कों में से पहला गैर-लुप्त प्रविष्टि लौटाता है:
df %>% mutate(age_final = coalesce(age, age_estimated, 0))
आपने जो भी बदलाव किए हैं, उनका रिकॉर्ड रखें। इनपुट करने से पहले एक फ़्लैग जोड़ें, ताकि बाद में आने वाला कोई भी मॉडल इस तथ्य से सीख सके कि कोई मान अनुपस्थित था:
df_titanic %>%
mutate(age_was_missing = is.na(age),
age = ifelse(is.na(age), mean(age, na.rm = TRUE), age))
R में लुप्त मानों को संभालना: विधि संदर्भ
इस ट्यूटोरियल में तीन दृष्टिकोणों को शामिल किया गया है:
- सभी लुप्त प्रेक्षणों को बाहर निकालें
- माध्य के साथ आरोपण करें
- मध्यिका के साथ आरोपण करें
नीचे दी गई तालिका में पहचान और हटाने की प्रक्रिया का सारांश दिया गया है:
| पुस्तकालय | उद्देश्य | Code |
|---|---|---|
| आधार | लुप्त टिप्पणियों की सूची बनाएं |
colnames(df)[apply(df, 2, anyNA)] |
| आधार | NA मान वाली सभी पंक्तियों को हटा दें |
na.omit(df) |
माध्य या मध्यिका के साथ आरोपण दो तरीकों से किया जा सकता है
- लागू करें का उपयोग करना
- सैप्ली का उपयोग
| विधि | विवरण | फायदे | नुकसान |
|---|---|---|---|
| चरण दर चरण आवेदन करें | लुप्त स्तंभों की जांच करें, माध्य/माध्यिका की गणना करें, मान संग्रहीत करें, mutate() से प्रतिस्थापित करें | आप अनुमानित माध्य या माध्यिका देख सकते हैं। | अधिक निष्पादन समय। बड़े डेटासेट के साथ धीमा हो सकता है |
| सैप्ली के साथ त्वरित तरीका | sapply() और data.frame() का उपयोग करके स्वचालित रूप से लुप्त मानों को खोजें और उन्हें माध्य/माध्यिका से बदलें | छोटा और तेज़ कोड | अनुमानित मान कभी प्रदर्शित नहीं किए जाते हैं। |




