रिक्त कक्षों को "NA" में बदलें


80

यहां मेरे डेटा का लिंक दिया गया है।

मेरा लक्ष्य सभी रिक्त कोशिकाओं को श्रेणीबद्ध या संख्यात्मक मानों के बावजूद "NA" असाइन करना है। मैं na.strings = "" का उपयोग कर रहा हूं । लेकिन यह सभी रिक्त कोशिकाओं को NA असाइन नहीं कर रहा है।

## reading the data
dat <- read.csv("data2.csv")
head(dat)
  mon hr        acc   alc sex spd axles door  reg                                 cond1 drug1
1   8 21 No Control  TRUE   F   0     2    2      Physical Impairment (Eyes, Ear, Limb)     A
2   7 20 No Control FALSE   M 900     2    2                                Inattentive     D
3   3  9 No Control FALSE   F 100     2    2 2004                                Normal     D
4   1 15 No Control FALSE   M   0     2    2      Physical Impairment (Eyes, Ear, Limb)     D
5   4 21 No Control FALSE      25    NA   NA                                                D
6   4 20 No Control    NA   F  30     2    4                Drinking Alcohol - Impaired     D
       inj1 PED_STATE st rac1
1     Fatal      <NA>  F <NA>
2  Moderate      <NA>  F <NA>
3  Moderate      <NA>  M <NA>
4 Complaint      <NA>  M <NA>
5 Complaint      <NA>  F <NA>
6  Moderate      <NA>  M <NA>


## using na.strings
dat2 <- read.csv("data2.csv", header=T, na.strings="")
head(dat2)
  mon hr        acc   alc sex spd axles door  reg                                 cond1 drug1
1   8 21 No Control  TRUE   F   0     2    2 <NA> Physical Impairment (Eyes, Ear, Limb)     A
2   7 20 No Control FALSE   M 900     2    2 <NA>                           Inattentive     D
3   3  9 No Control FALSE   F 100     2    2 2004                                Normal     D
4   1 15 No Control FALSE   M   0     2    2 <NA> Physical Impairment (Eyes, Ear, Limb)     D
5   4 21 No Control FALSE      25    NA   NA <NA>                                  <NA>     D
6   4 20 No Control    NA   F  30     2    4 <NA>           Drinking Alcohol - Impaired     D
       inj1 PED_STATE st rac1
1     Fatal        NA  F   NA
2  Moderate        NA  F   NA
3  Moderate        NA  M   NA
4 Complaint        NA  M   NA
5 Complaint        NA  F   NA
6  Moderate        NA  M   NA

कृपया टेबल्स और ईआरडी सहित - टेक्स्ट के लिए, चित्रों / लिंक का उपयोग न करें अन्य पाठ से भावानुवाद या उद्धरण। केवल उन्हीं चित्रों का उपयोग करें जिन्हें पाठ के रूप में या पाठ को बढ़ाने के लिए व्यक्त नहीं किया जा सकता है। छवियां खोजी नहीं जा सकतीं, जिन्हें कट या पेस्ट नहीं किया जा सकता है। एक छवि के साथ एक किंवदंती / कुंजी और स्पष्टीकरण शामिल करें। अपनी पोस्ट को स्व-निहित बनाएं। संपादित कार्यों का उपयोग करके चित्र / लिंक डालें।
फिलीपिसे

जवाबों:


98

मैं मान रहा हूँ कि आप पंक्ति 5 कॉलम "सेक्स" के बारे में बात कर रहे हैं। यह मामला हो सकता है कि data2.csv फ़ाइल में, सेल में एक स्थान होता है और इसलिए R द्वारा खाली नहीं माना जाता है।

इसके अलावा, मैंने देखा कि पंक्ति 5 कॉलम "एक्सल" और "डोर" में, data2.csv से पढ़े गए मूल मान स्ट्रिंग "NA" हैं। आप शायद उन लोगों के साथ भी व्यवहार करना चाहते हैं। यह करने के लिए,

dat2 <- read.csv("data2.csv", header=T, na.strings=c("","NA"))

संपादित करें:

मैंने आपका data2.csv डाउनलोड किया। हां, पंक्ति 5 कॉलम "सेक्स" में एक स्थान है। इसलिए आप यह चाहते हैं

na.strings=c(""," ","NA")

34

आप रिक्त स्थान के कई म्यूटेशन को बदलने के लिए gsub का उपयोग कर सकते हैं, जैसे "" या एक स्थान, NA होने के लिए।

data= data.frame(cats=c('', ' ', 'meow'), dogs=c("woof", " ", NA))
apply(data, 2, function(x) gsub("^$|^ $", NA, x))

2
gsub("^$", NA, trimws(x))सेल के भीतर एक से अधिक स्थान को संभालने के लिए भी उपयोग कर सकते हैं । हालाँकि, इन दोनों दृष्टिकोणों से सावधान रहें सभी कॉलमों को स्ट्रिंग / कैरेक्टर वैरिएबल में परिवर्तित करें (यदि पहले से नहीं है)।
JWilliman

27

एक अधिक आंख के अनुकूल समाधान का उपयोग dplyrहोगा

require(dplyr)

## fake blank cells
iris[1,1]=""

## define a helper function
empty_as_na <- function(x){
    if("factor" %in% class(x)) x <- as.character(x) ## since ifelse wont work with factors
    ifelse(as.character(x)!="", x, NA)
}

## transform all columns
iris %>% mutate_each(funs(empty_as_na)) 

केवल कॉलम के सबसेट में सुधार लागू करने के लिए आप dplyr के कॉलम मिलान वाक्यविन्यास का उपयोग करके ब्याज के कॉलम निर्दिष्ट कर सकते हैं। उदाहरण:mutate_each(funs(empty_as_na), matches("Width"), Species)

यदि आपके पास तालिका में वे दिनांक हैं जिनमें आपको अधिक प्रकार के असुरक्षित संस्करण का उपयोग करने पर विचार करना चाहिएifelse


11
एक नया पुस्तकालय कैसे जोड़ रहा है, एक नया फ़ंक्शन बनाना अधिक आंख के अनुकूल है ? और मुझे लगता है कि आपको आवश्यकता होगी ifelse(x %in% c(""," ","NA"), NA, x)
zx8754

4
फ़ंक्शन का उपयोग करने के साथ-साथ mutate_eachअधिक लचीलापन और पुन: प्रयोज्य पैटर्न देता है। dplyrआजकल आर-वर्कफ़्लोज़ में सर्वव्यापी है और इसका उत्तर केवल आत्म-निहित बनाने के लिए जोड़ा गया था। मुझे लगता x!=""है कि यहाँ सही है, क्योंकि न तो "" और न ही "एनए" रिक्त हैं। इसके अलावा @ स्कार्की का जवाब डेटा-फ्रेम वाले नंबरों के लिए विफल रहता है, और @ बैडो वास्तव में मौजूदा डेटा.फ्रेम के लिए समस्या का समाधान नहीं करते हैं, इसलिए कोई अन्य उत्तर सामान्य फैशन में अभी तक सवाल का जवाब नहीं देता है। मैं बेहतर समाधानों के बारे में जानकर खुश हूं।
Holger Brandl

1
Dplyr आजकल आर-वर्कफ़्लोज़ में सर्वव्यापी है - नहीं, नहीं। और क्या " और @ बैडो वास्तव में मौजूदा data.frames के लिए समस्या का समाधान नहीं करता है " यहां तक ​​कि इसका मतलब है? क्या आप उस कथन पर थोड़ा विस्तार कर सकते हैं?
डेविड आरेनबर्ग

10
बैडो ने विवरण दिया कि read.csvरिक्त कोशिकाओं को एनए में बदलने के लिए कॉन्फ़िगर कैसे करें जब एक फ़ाइल से तालिका पढ़ते हैं। हालांकि, चूंकि सवाल का शीर्षक "एनएवाई ब्लैंक सेल्स को" एनए "करने के लिए है, इसलिए एक पूर्ण उत्तर को उस स्थिति को कवर करना चाहिए जहां एक डेटा.फ्रेम पहले से ही पर्यावरण में है और उपयोगकर्ता रिक्त कोशिकाओं से छुटकारा पाना चाहता है।
होल्गर ब्रांडल

1
यह ओपी के लिए क्या देख रहा था, यह नहीं हो सकता है, लेकिन इससे मुझे खाली स्ट्रिंग और एनए सहित लापता मूल्यों को गिनने में मदद मिली। df %>% mutate_all(funs(empty_as_na)) %>% summarize_all(funs(sum(is.na(.))))जबकि dplyr गोद लेने में व्यापक हो सकता है या नहीं हो सकता है, यह आर उपयोगकर्ताओं के एक बड़े उपसमूह में लोकप्रियता का आनंद लेता है, मेरे सहित, इसलिए इस समाधान के लिए धन्यवाद।
17

22

यह काम कर जाना चाहिए

dat <- dat %>% mutate_all(na_if,"")

1
मैंने कोशिश की कि एक sf ऑब्जेक्ट पर, और यह एक पार्सिंग एरर फेंक दिया: अज्ञात WKB टाइप 12. लगता है कि ज्योमेट्रीज में कुछ को बदलने की कोशिश की गई थी।
एएई

15

मैं हाल ही में इसी तरह के मुद्दों में भाग गया, और यही मेरे लिए काम किया।

यदि चर संख्यात्मक है, तो एक साधारण df$Var[df$Var == ""] <- NAपर्याप्त होना चाहिए। लेकिन अगर चर एक कारक है, तो आपको इसे पहले चरित्र में बदलने की आवश्यकता है, फिर ""कोशिकाओं को उस मूल्य के साथ बदलें जो आप चाहते हैं, और इसे वापस कारक में परिवर्तित करें। तो मामले में अपने Sexचर, मुझे लगता है कि यह एक कारक होगा और यदि आप खाली सेल को बदलना चाहते हैं, तो मैं निम्नलिखित कार्य करूंगा:

df$Var <- as.character(df$Var)
df$Var[df$Var==""] <- NA
df$Var <- as.factor(df$Var)

3

यदि आप बाहरी फ़ाइलों को पढ़ने के लिए हेवन या विदेशी पैकेज का उपयोग करते हैं तो मेरा कार्य खाता कारक, चरित्र वेक्टर और संभावित विशेषताओं को ध्यान में रखता है। इसके अलावा यह अलग-अलग स्व-परिभाषित na.strings के मिलान की अनुमति देता है। सभी स्तंभों को बदलने के लिए, बस lappy का उपयोग करें:df[] = lapply(df, blank2na, na.strings=c('','NA','na','N/A','n/a','NaN','nan'))

अधिक टिप्पणियां देखें:

#' Replaces blank-ish elements of a factor or character vector to NA
#' @description Replaces blank-ish elements of a factor or character vector to NA
#' @param x a vector of factor or character or any type
#' @param na.strings case sensitive strings that will be coverted to NA. The function will do a trimws(x,'both') before conversion. If NULL, do only trimws, no conversion to NA.
#' @return Returns a vector trimws (always for factor, character) and NA converted (if matching na.strings). Attributes will also be kept ('label','labels', 'value.labels').
#' @seealso \code{\link{ez.nan2na}}
#' @export
blank2na = function(x,na.strings=c('','.','NA','na','N/A','n/a','NaN','nan')) {
    if (is.factor(x)) {
        lab = attr(x, 'label', exact = T)
        labs1 <- attr(x, 'labels', exact = T)
        labs2 <- attr(x, 'value.labels', exact = T)

        # trimws will convert factor to character
        x = trimws(x,'both')
        if (! is.null(lab)) lab = trimws(lab,'both')
        if (! is.null(labs1)) labs1 = trimws(labs1,'both')
        if (! is.null(labs2)) labs2 = trimws(labs2,'both')

        if (!is.null(na.strings)) {
            # convert to NA
            x[x %in% na.strings] = NA
            # also remember to remove na.strings from value labels 
            labs1 = labs1[! labs1 %in% na.strings]
            labs2 = labs2[! labs2 %in% na.strings]
        }

        # the levels will be reset here
        x = factor(x)

        if (! is.null(lab)) attr(x, 'label') <- lab
        if (! is.null(labs1)) attr(x, 'labels') <- labs1
        if (! is.null(labs2)) attr(x, 'value.labels') <- labs2
    } else if (is.character(x)) {
        lab = attr(x, 'label', exact = T)
        labs1 <- attr(x, 'labels', exact = T)
        labs2 <- attr(x, 'value.labels', exact = T)

        # trimws will convert factor to character
        x = trimws(x,'both')
        if (! is.null(lab)) lab = trimws(lab,'both')
        if (! is.null(labs1)) labs1 = trimws(labs1,'both')
        if (! is.null(labs2)) labs2 = trimws(labs2,'both')

        if (!is.null(na.strings)) {
            # convert to NA
            x[x %in% na.strings] = NA
            # also remember to remove na.strings from value labels 
            labs1 = labs1[! labs1 %in% na.strings]
            labs2 = labs2[! labs2 %in% na.strings]
        }

        if (! is.null(lab)) attr(x, 'label') <- lab
        if (! is.null(labs1)) attr(x, 'labels') <- labs1
        if (! is.null(labs2)) attr(x, 'value.labels') <- labs2
    } else {
        x = x
    }
    return(x)
}

3

तुम भी उपयोग कर सकते हैं mutate_atमेंdplyr

dat <- dat %>%
mutate_at(vars(colnames(.)),
        .funs = funs(ifelse(.=="", NA, as.character(.))))

बदलने के लिए व्यक्तिगत कॉलम चुनें:

dat <- dat %>%
mutate_at(vars(colnames(.)[names(.) %in% c("Age","Gender")]),
        .funs = funs(ifelse(.=="", NA, as.character(.))))

जैसा कि ऊपर लिखा गया है (dplyr 0.8.0 ऊपर) यह बदल गया है। इससे पहले, funs()में था .funs (funs(name = f(.))। इसके बजाय funs, अब हम उपयोग करते हैंlist (list(name = ~f(.)))

ध्यान दें कि कॉलम नामों को सूचीबद्ध करने का एक बहुत सरल तरीका भी है! (कॉलम और कॉलम इंडेक्स काम दोनों का नाम)

dat <- dat %>%
mutate_at(.vars = c("Age","Gender"),
    .funs = list(~ifelse(.=="", NA, as.character(.))))

2

जबकि कई विकल्प अच्छे से काम करते हैं, मुझे chrसमस्याग्रस्त करने के लिए गैर-लक्ष्य चर का बल मिला । उपयोग करना ifelseऔर इसके greplभीतर lapplyलक्ष्य-निर्धारण प्रभाव (सीमित परीक्षण में) को हल करता है। में गंदी की नियमित अभिव्यक्ति का उपयोग करना grepl:

set.seed(42)
x1 <- sample(c("a","b"," ", "a a", NA), 10, TRUE)
x2 <- sample(c(rnorm(length(x1),0, 1), NA), length(x1), TRUE)

df <- data.frame(x1, x2, stringsAsFactors = FALSE)

चरित्र वर्ग के लिए जबरदस्ती की समस्या:

df2 <- lapply(df, function(x) gsub("^$|^ $", NA, x))
lapply(df2, class)

$ x1 [1] "चरित्र"

$ x2 [1] "चरित्र"

इफ्लेसी के उपयोग के साथ संकल्प:

df3 <- lapply(df, function(x) ifelse(grepl("^$|^ $", x)==TRUE, NA, x))
lapply(df3, class)

$ x1 [1] "चरित्र"

$ x2 [1] "संख्यात्मक"


2

मुझे संदेह है कि सभी के पास पहले से ही एक उत्तर है, हालांकि अगर कोई देख रहा है, तो dplyr na_if () होगा (मेरे दृष्टिकोण से) उन लोगों के अधिक कुशल:

# Import CSV, convert all 'blank' cells to NA
dat <- read.csv("data2.csv") %>% na_if("")

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

dat <- read_csv("data2.csv", na = c("", "NA", "N/A"))

रीडर्स संस्करण बनाम बेस आर में अंडरस्कोर नोट करें "।" read_csv में।

उम्मीद है कि यह मदद करता है जो पोस्ट पर घूमता है!


0

आप सिर्फ इस्तेमाल नहीं कर सकते

dat <- read.csv("data2.csv",na.strings=" ",header=TRUE)

सभी रिक्त स्थान को NA में रूपांतरित करना चाहिए क्योंकि डेटा आपके उद्धरण के बीच एक स्थान सुनिश्चित करने के लिए पढ़ा जाता है


यदि आप उद्धरणों के बीच का स्थान नहीं रखते हैं तो क्या होगा?
नेनेका

0

डेटा का उपयोग करने वाले किसी समाधान के बारे में सोच रहे लोगों के लिए । यहाँ, मैंने अपने गीथूब पर उपलब्ध एक फ़ंक्शन लिखा है:

library(devtools)
source_url("https://github.com/YoannPa/Miscellaneous/blob/master/datatable_pattern_substitution.R?raw=TRUE")
dt.sub(DT = dat2, pattern = "^$|^ $",replacement = NA)
dat2

फ़ंक्शन प्रत्येक कॉलम के माध्यम से जाता है, यह पहचानने के लिए कि किस कॉलम में पैटर्न मैच होते हैं। फिर gsub()पैटर्न के लिए मैच वाले कॉलम पर aplied है "^$|^ $", NAएस द्वारा मैचों को प्रतिस्थापित करने के लिए ।

मैं इसे तेजी से बनाने के लिए इस फंक्शन में सुधार करता रहूंगा।



-3

आर में dplyrसे स्थापित करके कॉल पैकेजcran

library(dplyr)

(file)$(colname)<-sub("-",NA,file$colname) 

यह एक विशेष कॉलम में सभी रिक्त सेल को NA के रूप में परिवर्तित करेगा

यदि कॉलम में "-", "" है, तो इस तरह से इसे रिक्त सेल के प्रकार के अनुसार कोड में बदल दें

जैसे अगर मुझे "-" के बजाय "" जैसा एक रिक्त कक्ष मिलता है, तो इस कोड का उपयोग करें:

(file)$(colname)<-sub("", NA, file$colname)

1
यह उत्तर dplyrइसे लोड करने के बाद उपयोग नहीं करता है और यह ओपी की तरह "सभी कॉलम" के लिए अच्छी तरह से पैमाने पर नहीं है।
ग्रिगोर थॉमस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.