2013-04-18 29 views
11

Chcę podać typy brakujących wartości. Mam dane, które mają różne typy brakujące i próbuję zakodować te wartości jako brakujące w R, ale szukam rozwiązania, ale wciąż mogę je rozróżnić.Określanie różnych typów brakujących wartości (NA)

Say mam pewne dane, które wygląda tak,

set.seed(667) 
df <- data.frame(a = sample(c("Don't know/Not sure","Unknown","Refused","Blue", "Red", "Green"), 20, rep=TRUE), b = sample(c(1, 2, 3, 77, 88, 99), 10, rep=TRUE), f = round(rnorm(n=10, mean=.90, sd=.08), digits = 2), g = sample(c("C","M","Y","K"), 10, rep=TRUE)); df 
#      a b f g 
# 1    Unknown 2 0.78 M 
# 2    Refused 2 0.87 M 
# 3     Red 77 0.82 Y 
# 4     Red 99 0.78 Y 
# 5    Green 77 0.97 M 
# 6    Green 3 0.99 K 
# 7     Red 3 0.99 Y 
# 8    Green 88 0.84 C 
# 9    Unknown 99 1.08 M 
# 10    Refused 99 0.81 C 
# 11    Blue 2 0.78 M 
# 12    Green 2 0.87 M 
# 13    Blue 77 0.82 Y 
# 14 Don't know/Not sure 99 0.78 Y 
# 15    Unknown 77 0.97 M 
# 16    Refused 3 0.99 K 
# 17    Blue 3 0.99 Y 
# 18    Green 88 0.84 C 
# 19    Refused 99 1.08 M 
# 20     Red 99 0.81 C 

Gdybym teraz zrobić dwie tabele moje brakujące wartości ("Don't know/Not sure","Unknown","Refused" i 77, 88, 99) są jak zwykłe dane,

table(df$a,df$g) 
#      C K M Y 
# Blue    0 0 1 2 
# Don't know/Not sure 0 0 0 1 
# Green    2 1 2 0 
# Red     1 0 0 3 
# Refused    1 1 2 0 
# Unknown    0 0 3 0 

i

table(df$b,df$g) 
# C K M Y 
# 2 0 0 4 0 
# 3 0 2 0 2 
# 77 0 0 2 2 
# 88 2 0 0 0 
# 99 2 0 2 2 

Przekształcam teraz trzy poziomy współczynników "Don't know/Not sure","Unknown","Refused" do <NA>

is.na(df[,c("a")]) <- df[,c("a")]=="Don't know/Not sure"|df[,c("a")]=="Unknown"|df[,c("a")]=="Refused" 

i wyjąć pusty poziomy

df$a <- factor(df$a) 

i to samo zrobić z wartościami liczbowymi 77, 88, i 99

is.na(df) <- df=="77"|df=="88"|df=="99" 

table(df$a, df$g, useNA = "always")  
#  C K M Y <NA> 
# Blue 0 0 1 2 0 
# Green 2 1 2 0 0 
# Red 1 0 0 3 0 
# <NA> 1 1 5 1 0 

table(df$b,df$g, useNA = "always") 
#  C K M Y <NA> 
# 2 0 0 4 0 0 
# 3 0 2 0 2 0 
# <NA> 4 0 4 4 0 

Teraz brakujące kategorie przekodować do NA ale wszystkie są zgrupowane razem. Czy istnieje sposób na przekodowanie czegoś jako brakującego, ale zachowują wartości oryginalne? Chcę, aby R do wątku "Don't know/Not sure","Unknown","Refused" i 77, 88, 99 jako brakujące, ale chcę móc nadal mieć informacje w zmiennej.

+0

Co powiesz na dodanie kolejnej kolumny do 'df' zwanego' isNA', które będzie miało wartość true, jeśli brakuje wartości? lub kolumna 'isNA' może bezpośrednio pomieścić' NA' i '0'. To zależy od reszty twojego kodu. – Nishanth

+0

To by działało poprawnie, ale jest to bardziej obejście niż rozwiązanie, które działałoby * bezproblemowo * z resztą mojego kodu - jak również wskazujesz. Czy chciałbyś zademonstrować to w przykładzie? –

+0

Trudno jest przewidzieć wpływ na resztę kodu. możesz napisać własną 'my.table', która używa' my.is.na', która zwraca 'TRUE' dla" Nie wiem/nie jestem pewien "," Nieznany "," Odmówiono " – Nishanth

Odpowiedz

5

Aby zachować oryginalne wartości, można utworzyć nowe kolumny, gdzie kodować informacje na, na przykład:

df <- transform(df,b.na = ifelse(b %in% c('77','88','99'),NA,b)) 
df <- transform(df,a.na = ifelse(a %in% 
         c("Don't know/Not sure","Unknown","Refused"),NA,a)) 

Następnie można zrobić coś takiego:

table(df$b.na , df$g) 
    C K M Y 
    2 0 0 4 0 
    3 0 2 0 2 

Inną opcją bez tworząc nowe kolumny, należy użyć opcji exclude, aby ustawić niepotrzebne wartości na NULL (różne wartości):

table(df$a,df$g, 
     exclude=c('77','88','99',"Don't know/Not sure","Unknown","Refused")) 
     C K M Y 
    Blue 0 0 1 2 
    Green 2 1 2 0 
    Red 1 0 0 3 

Możesz zdefiniować niektóre stałe globalne (nawet te nie są polecane), aby zgrupować "brakujące wartości" i wykorzystać je w pozostałej części programu. Coś takiego:

B_MISSING <- c('77','88','99') 
A_MISSING <- c("Don't know/Not sure","Unknown","Refused") 
+1

Dziękuję za odpowiedź na moje pytanie. Nie wiedziałem o opcji 'exclude'. To interesujące rozwiązanie. Wciąż jestem nieco zaskoczony, że R ma tylko jedną kategorię brakujących wartości. –

+2

@EricFail R mają jeden brak są zasadniczo wartościami logicznymi, ale mogą również mieć różne typy: 'NA_integer_, NA_real_, NA_complex_ i NA_character_'. Możesz zobaczyć moją edycję dla "globalnego" rozwiązania. – agstudy

+8

Ściśle mówiąc, nie są to (wszystkie) błędy. "Nie wiem" nie jest brakujące, jest to poprawna kategoria odpowiedzi, aw wielu przypadkach należy je traktować jako taką. "Odrzucony" zawiera również informacje, natomiast "Nieznany" prawdopodobnie nie jest prawdziwy. Po prostu utworzyłbym dodatkową kolumnę z tymi trzema podkategoriami i odnosiłbym się do nich zawsze, gdy potrzebowałem, podczas gdy używałbym zwykłej NA dla technik statystycznych, które nie różnicują. –

18

Według mojej wiedzy, baza R nie mają wbudowany sposób obsłużyć różne NA typy. (redaktor: Czyni. NA_integer_, NA_real_, NA_complex_ i NA_character Zobacz ?base::NA).

Jedną z opcji jest użycie pakietu, który robi to, na przykład "memisc". To trochę dodatkowej pracy, ale wydaje się, że robisz to, czego szukasz.To jest przykład:

Najpierw twoje dane. Zrobiłem kopię, ponieważ wprowadzimy całkiem istotne zmiany w zestawie danych i zawsze dobrze jest mieć kopię zapasową.

set.seed(667) 
df <- data.frame(a = sample(c("Don't know/Not sure", "Unknown", 
           "Refused", "Blue", "Red", "Green"), 
          20, replace = TRUE), 
       b = sample(c(1, 2, 3, 77, 88, 99), 10, 
          replace = TRUE), 
       f = round(rnorm(n = 10, mean = .90, sd = .08), 
          digits = 2), 
       g = sample(c("C", "M", "Y", "K"), 10, 
          replace = TRUE)) 
df2 <- df 

Miejmy czynnikiem zmienna "a":

df2$a <- factor(df2$a, 
       levels = c("Blue", "Red", "Green", 
          "Don't know/Not sure", 
          "Refused", "Unknown"), 
       labels = c(1, 2, 3, 77, 88, 99)) 

Załaduj "memisc" Biblioteka:

library(memisc) 

Teraz konwertować zmienne "a" i "b" do item sw "memisc":

df2$a <- as.item(as.character(df2$a), 
        labels = structure(c(1, 2, 3, 77, 88, 99), 
            names = c("Blue", "Red", "Green", 
               "Don't know/Not sure", 
               "Refused", "Unknown")), 
        missing.values = c(77, 88, 99)) 
df2$b <- as.item(df2$b, 
       labels = c(1, 2, 3, 77, 88, 99), 
       missing.values = c(77, 88, 99)) 

Robiąc to, mieć nowy typ danych. Porównaj poniższe:

as.factor(df2$a) 
# [1] <NA> <NA> Red Red Green Green Red Green <NA> <NA> Blue 
# [12] Green Blue <NA> <NA> <NA> Blue Green <NA> Red 
# Levels: Blue Red Green 
as.factor(include.missings(df2$a)) 
# [1] *Unknown    *Refused    Red     
# [4] Red     Green    Green    
# [7] Red     Green    *Unknown    
# [10] *Refused    Blue     Green    
# [13] Blue     *Don't know/Not sure *Unknown    
# [16] *Refused    Blue     Green    
# [19] *Refused    Red     
# Levels: Blue Red Green *Don't know/Not sure *Refused *Unknown 

Możemy wykorzystać te informacje do tworzenia tabel zachowujących się zgodnie z opisem, przy jednoczesnym zachowaniu wszystkich oryginalnych informacji.

table(as.factor(include.missings(df2$a)), df2$g) 
#      
#      C K M Y 
# Blue     0 0 1 2 
# Red     1 0 0 3 
# Green    2 1 2 0 
# *Don't know/Not sure 0 0 0 1 
# *Refused    1 1 2 0 
# *Unknown    0 0 3 0 
table(as.factor(df2$a), df2$g) 
#   
#   C K M Y 
# Blue 0 0 1 2 
# Red 1 0 0 3 
# Green 2 1 2 0 
table(as.factor(df2$a), df2$g, useNA="always") 
#   
#   C K M Y <NA> 
# Blue 0 0 1 2 0 
# Red 1 0 0 3 0 
# Green 2 1 2 0 0 
# <NA> 1 1 5 1 0 

Tabele dla kolumny numerycznej z brakującymi danymi zachowują się w ten sam sposób.

table(as.factor(include.missings(df2$b)), df2$g) 
#  
#  C K M Y 
# 1 0 0 0 0 
# 2 0 0 4 0 
# 3 0 2 0 2 
# *77 0 0 2 2 
# *88 2 0 0 0 
# *99 2 0 2 2 
table(as.factor(df2$b), df2$g, useNA="always") 
#  
#  C K M Y <NA> 
# 1 0 0 0 0 0 
# 2 0 0 4 0 0 
# 3 0 2 0 2 0 
# <NA> 4 0 4 4 0 

Jako bonus, można uzyskać obiekt do generowania ładne codebook s:

> codebook(df2$a) 
======================================================================== 

    df2$a 

------------------------------------------------------------------------ 

    Storage mode: character 
    Measurement: nominal 
    Missing values: 77, 88, 99 

      Values and labels N Percent 

    1 'Blue'     3 25.0 15.0 
    2 'Red'     4 33.3 20.0 
    3 'Green'     5 41.7 25.0 
    77 M 'Don't know/Not sure' 1   5.0 
    88 M 'Refused'    4  20.0 
    99 M 'Unknown'    3  15.0 

Jednak ja również proponuję przeczytać the comment od @ Maxim.K o czym naprawdę stanowi brakujące wartości.

+1

+1 bardzo dobra szczegółowa odpowiedź! Lubię "*" w rownames, gdy 'include.missings' :) – agstudy

+0

Dziękuję za dobrą szczegółową odpowiedź, jak zaznacza również @agstudy. –

+0

+1 bardzo szczegółowy, miły. R ma sposób radzenia sobie z różnymi rodzajami NA, ale nie wiem, czy możesz z niego skorzystać. Musi zrobić, aby móc wykonać 'class (c (1,2, NA))', która jest '" numeryczna "i' klasa (c ("a", "b", NA)) 'która jest' " znak "'? –

3

Jeśli chcesz pozostać przy wartościach liczbowych, można użyć NA, Inf, -Inf i NaN dla różnych brakujących wartości. Następnie można użyć is.finite rozróżnienie między nimi i normalnych wartości:

> x <- c(NA, Inf, -Inf, NaN, 1) 
> is.finite(x) 
[1] FALSE FALSE FALSE FALSE TRUE 

Można mieć specjalną funkcję drukowania, które wyświetla je w bardziej znaczący sposób lub nawet stworzyć specjalną klasę, ale nawet bez tego byłoby to podzielić dane na skończone i wielokrotne wartości nieskończone.

Powiązane problemy