सभी 0 मानों को NA में बदलें


145

मेरे पास कुछ संख्यात्मक कॉलम के साथ एक डेटाफ्रेम है। कुछ पंक्ति में 0 मान होता है जिसे सांख्यिकीय विश्लेषण में शून्य माना जाना चाहिए। NULL को R में सभी 0 मान को बदलने का सबसे तेज़ तरीका क्या है?


17
मुझे नहीं लगता कि आप चाहते हैं / NULL मानों के साथ बदल सकते हैं, लेकिन NA उस उद्देश्य को R lingo में प्रस्तुत करता है।
चेस

जवाबों:


244

सभी शून्य को NA में बदलना:

df[df == 0] <- NA



व्याख्या

1. यह वह नहीं है NULLजिसे आपको शून्य से बदलना चाहिए। यह में कहते हैं ?'NULL',

NULL R में अशक्त वस्तु का प्रतिनिधित्व करता है

जो अद्वितीय है और, मुझे लगता है, इसे सबसे असंक्रामक और खाली वस्तु के रूप में देखा जा सकता है। 1 तो यह इतना आश्चर्य की बात नहीं है कि

data.frame(x = c(1, NULL, 2))
#   x
# 1 1
# 2 2

यही है, आर इस अशक्त वस्तु के लिए कोई स्थान आरक्षित नहीं करता है। 2 इस बीच, ?'NA'हम इसे देख रहे हैं

NA लंबाई 1 का एक तार्किक स्थिरांक है जिसमें एक लापता मान सूचक होता है। NA कच्चे को छोड़कर किसी भी अन्य वेक्टर प्रकार के लिए मजबूर किया जा सकता है।

महत्वपूर्ण रूप से, NAलंबाई 1 की है ताकि R इसके लिए कुछ स्थान सुरक्षित रखे। उदाहरण के लिए,

data.frame(x = c(1, NA, 2))
#    x
# 1  1
# 2 NA
# 3  2

इसके अलावा, डेटा फ्रेम संरचना में सभी स्तंभों को समान संख्या में तत्वों की आवश्यकता होती है ताकि कोई "छेद" (यानी, NULLमान) न हो।

अब आप NULLकम से कम एक शून्य वाले सभी पंक्तियों को पूरी तरह से हटाने के अर्थ में डेटा फ्रेम में शून्य को बदल सकते हैं । का उपयोग करते समय, जैसे, var, cov, या cor, कि वास्तव में बराबर पहले से शून्य की जगह है NAऔर का मान सेट useके रूप में "complete.obs"। आमतौर पर, हालांकि, यह असंतोषजनक है क्योंकि यह अतिरिक्त सूचना हानि की ओर जाता है।

2. किसी प्रकार के लूप को चलाने के बजाय, समाधान में मैं df == 0वेक्टराइजेशन का उपयोग करता हूं । df == 0रिटर्न (इसे आज़माएं) उसी आकार का एक मैट्रिक्स df, जैसा कि प्रविष्टियों के साथ TRUEऔर FALSE। इसके अलावा, हमें इस मैट्रिक्स को सब्मिट करने की अनुमति है [...](देखें ?'[')। अंत में, जबकि परिणाम df[df == 0]पूरी तरह से सहज है, यह अजीब लग सकता df[df == 0] <- NAहै जो वांछित प्रभाव देता है। असाइनमेंट ऑपरेटर <-वास्तव में हमेशा इतना स्मार्ट नहीं होता है और कुछ अन्य वस्तुओं के साथ इस तरह से काम नहीं करता है, लेकिन डेटा फ्रेम के साथ ऐसा करता है; देखते हैं ?'<-'


1 सेट सिद्धांत में खाली सेट किसी तरह से संबंधित लगता है।
2 सेट सिद्धांत के साथ एक और समानता: खाली सेट हर सेट का एक सबसेट है, लेकिन हम इसके लिए कोई स्थान आरक्षित नहीं करते हैं।


3
डेटाटेबल ऑब्जेक्ट के लिए बराबर सिंटैक्स क्या होगा?
itpetersen

6
मुझे लगता है कि आपको बहुत सारे वोट मिले हैं, लेकिन यह मत सोचो कि यह उचित रूप से "0" के मूल्यों के साथ गैर-संख्यात्मक स्तंभों के किनारे के मामलों को कवर करता है जिन्हें <NA> पर सेट करने का अनुरोध नहीं किया गया था।
IRTFM

33

मुझे लगता है कि आपके data.frame विभिन्न डेटाटिप्स का मिश्रण है और सभी स्तंभों को संशोधित करने की आवश्यकता नहीं है।

केवल कॉलम 12 से 18 (कुल 21 में से) को संशोधित करने के लिए, बस ऐसा करें

df[, 12:18][df[, 12:18] == 0] <- NA

यह मेरे लिए काम करता है, जबकि स्वीकृत उत्तर नहीं है
पैट्रिक कूलोमबे

23

[<-फ़ंक्शन के बिना एक वैकल्पिक तरीका :

एक नमूना डेटा फ्रेम dat(बेशर्मी से @ चेस के जवाब से कॉपी किया गया):

dat

  x y
1 0 2
2 1 2
3 1 1
4 2 1
5 0 0

शून्य NAको is.na<-फ़ंक्शन द्वारा प्रतिस्थापित किया जा सकता है:

is.na(dat) <- !dat


dat

   x  y
1 NA  2
2  1  2
3  1  1
4  2  1
5 NA NA

22

dplyr::na_if() एक विकल्प है:

library(dplyr)  

df <- data_frame(col1 = c(1, 2, 3, 0),
                 col2 = c(0, 2, 3, 4),
                 col3 = c(1, 0, 3, 0),
                 col4 = c('a', 'b', 'c', 'd'))

na_if(df, 0)
# A tibble: 4 x 4
   col1  col2  col3 col4 
  <dbl> <dbl> <dbl> <chr>
1     1    NA     1 a    
2     2     2    NA b    
3     3     3     3 c    
4    NA     4    NA d

14
#Sample data
set.seed(1)
dat <- data.frame(x = sample(0:2, 5, TRUE), y = sample(0:2, 5, TRUE))
#-----
  x y
1 0 2
2 1 2
3 1 1
4 2 1
5 0 0

#replace zeros with NA
dat[dat==0] <- NA
#-----
   x  y
1 NA  2
2  1  2
3  1  1
4  2  1
5 NA NA

12

क्योंकि किसी ने इसके लिए Data.Table संस्करण मांगा, और क्योंकि दिए गए data.frame समाधान data.table के साथ काम नहीं करते हैं, मैं नीचे समाधान प्रदान कर रहा हूं।

मूल रूप से, :=ऑपरेटर -> का उपयोग करेंDT[x == 0, x := NA]

library("data.table")

status = as.data.table(occupationalStatus)

head(status, 10)
    origin destination  N
 1:      1           1 50
 2:      2           1 16
 3:      3           1 12
 4:      4           1 11
 5:      5           1  2
 6:      6           1 12
 7:      7           1  0
 8:      8           1  0
 9:      1           2 19
10:      2           2 40


status[N == 0, N := NA]

head(status, 10)
    origin destination  N
 1:      1           1 50
 2:      2           1 16
 3:      3           1 12
 4:      4           1 11
 5:      5           1  2
 6:      6           1 12
 7:      7           1 NA
 8:      8           1 NA
 9:      1           2 19
10:      2           2 40

2
या for (j in names(DT)); set(DT,which(DT[[j]] == 0),j,NA)। मान खोजने और बदलने के लिए data.table का उपयोग करने की अधिक विस्तृत चर्चा के लिए यहां देखें ।
जॉलीमैन

4

आप केवल संख्यात्मक क्षेत्रों (जैसे कारकों को छोड़कर) के 0साथ बदल सकते हैं NA, लेकिन यह कॉलम-बाय-कॉलम आधार पर काम करता है:

col[col == 0 & is.numeric(col)] <- NA

एक फ़ंक्शन के साथ, आप इसे अपने संपूर्ण डेटा फ़्रेम में लागू कर सकते हैं:

changetoNA <- function(colnum,df) {
    col <- df[,colnum]
    if (is.numeric(col)) {  #edit: verifying column is numeric
        col[col == -1 & is.numeric(col)] <- NA
    }
    return(col)
}
df <- data.frame(sapply(1:5, changetoNA, df))

यद्यपि आप 1:5अपने डेटा फ़्रेम में या उसके साथ कॉलम की संख्या के साथ प्रतिस्थापित कर सकते हैं 1:ncol(df)


मुझे यकीन नहीं है कि यह सही समाधान है। कॉलम 6 और अधिक के बारे में क्या। वे कट जाएंगे।
userJT

इसलिए मैंने अंत में 1:5साथ बदलने का सुझाव दिया 1:ncol(df)। मैं समीकरण को अत्यधिक जटिल या पढ़ना मुश्किल नहीं बनाना चाहता था।
अलियम ब्रिट

लेकिन क्या होगा अगर कॉलम 6 और 7 में - डेटाटाइप चार है और कोई प्रतिस्थापन नहीं किया जाना चाहिए। मेरी समस्या में, मुझे केवल कॉलम 12 से 15 में प्रतिस्थापन की आवश्यकता है लेकिन पूरे डीएफ में 21 कॉलम हैं (कई को बिल्कुल भी नहीं छुआ जाना चाहिए)।
userJT

अपने डेटा फ़्रेम के 1:5लिए, आप अपने इच्छित कॉलम कॉलम को बदल सकते हैं, जैसे कि 12:15, लेकिन अगर आप यह पुष्टि करना चाहते हैं कि यह केवल संख्यात्मक कॉलम को प्रभावित करेगा, तो फ़ंक्शन के दूसरे लाइन को एक if स्टेटमेंट में लपेटें, जैसे if (is.numeric(col)) { col[col == -1 & is.numeric(col)] <- NA }:।
अलियम ब्रिट

0

यदि कोई व्यक्ति इसके विपरीत गूगल के माध्यम से यहां पहुंचता है (यानी कैसे सभी NAs को डेटा में बदल दिया जाए। 0 के साथ), तो उत्तर है

df[is.na(df)] <- 0

या

Dplyr / tidyverse का उपयोग करना

library(dplyr)
mtcars %>% replace(is.na(.), 0)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.