2011-08-25 14 views
5

Mam duży zestaw danych z 11 kolumnami i 100000 wierszy (na przykład), w których mam wartości 1,2,3,4. Gdzie 4 jest brakującą wartością. Brakuje niektórych wierszy. tj. 4 we wszystkich 11 kolumnach. Na przykład:Jak usunąć wiersz zawierający tylko brakujące wartości w R?

"4" "4" "4" "4" "4" "4" "4" "4" "4" "4" "4" 

Teraz potrzebuję usunąć tylko te rzędy, których kompletnie brakuje. W prostych słowach, chcę zachować wiersze z brakującą wartością mniejszą niż 11. Użyłem na.omit, ale to nie działa w moim przypadku.

Z góry dziękuję.

+0

Jak ktoś robi to będzie prawdopodobnie zależeć od informacji, które nie zostały przewidziane. Czy to jest ramka danych czy matryca? Czy wartości są przechowywane jako liczby całkowite lub znaki? Spróbuj edytować swoje pytanie za pomocą wyjścia z 'str (head (foo))' gdzie 'foo' to twoje dane. – joran

Odpowiedz

2

Prawdziwie szybkim sposobem byłoby użycie odrobiny matematyki. Zakładając, że dataframe nazywa datf

rsum <- rowSums(datf) 
datf <- datf[rowSums != 44,] #11 * 4 

(działa też na matrycy)

+2

Nie dam ci minus 1, ale takie podejście jest bardzo niebezpieczne. Działa w tym konkretnym przypadku, ale co się stanie, jeśli dodasz/usuniesz kolumnę? Zawsze staraj się rozwiązywać problemy w solidny sposób. – Andrie

+1

To nie zadziała, ponieważ wiersz może sumować się do 44 bez wszystkich elementów będących 4 (np. 'C (4,4,4,4,4,4,4,4,4,3,5)'). –

+0

Uwaga: w tym zestawie danych wartości mogą wynosić tylko 1, 2, 3 lub 4. – John

1

Coś jak to powinno załatwić sprawę (i powinien działać na obu matrycach i data.frames):

ac<-matrix(c("4","4","4","4","4","4","4","3","3","4","4", rep("4", 11)), nrow=2, ncol=11, byrow=TRUE) 

rowsToRemove<-which(apply(ac, 1, function(currow){ 
    all(currow=="4") 
})) 

Teraz można po prostu zrobić

newac<-ac[-rowsToRemove,] 
11

Być może najlepszym rozwiązaniem jest wykorzystanie Idiom R do pracy z brakującymi wartościami lub NA. Po zakodowaniu wartości NA możesz pracować z complete.cases, aby łatwo osiągnąć swój cel.

Tworzenie kilka przykładowych danych z brakującymi wartościami (tj wartość 4):

set.seed(123) 
m <- matrix(sample(1:4, 30, prob=c(0.3, 0.3, 0.3, 0.1), replace=TRUE), ncol=6) 
m[4, ] <- rep(4, 6) 

Wymień wszystkie wartości równe 4 z NA:

m[m==4] <- NA 
m 
    [,1] [,2] [,3] [,4] [,5] [,6] 
[1,] 1 1 NA 2 2 2 
[2,] 2 3 3 1 2 3 
[3,] 3 2 2 1 2 3 
[4,] NA NA NA NA NA NA 
[5,] NA 3 1 NA 2 1 

Teraz możesz korzystać z wielu funkcji, które radzić sobie z wartościami NA. Na przykład, complete.cases powróci tylko, zgadliście, kompletne przypadki:

m[complete.cases(m), ] 

    [,1] [,2] [,3] [,4] [,5] [,6] 
[1,] 2 3 3 1 2 3 
[2,] 3 2 2 1 2 3 

Aby uzyskać więcej informacji, zobacz ?complete.cases lub ?na.fail w pakiecie stats.

+0

To nie jest pytanie. OP chce usunąć tylko te rzędy, których kompletnie brakuje. – Kenji

2

To najszybszy rozwiązanie mogę myśleć. Użyję przykładowych danych podobnych do @Andrie.

set.seed(21) 
m <- matrix(sample(1:6, 110, replace=TRUE), ncol=11) 
missVal <- 4 
m[4, ] <- rep(missVal, 11) 
m <- m[ rowSums((m==missVal)) != NCOL(m), ] 

Ostatnia linia działa, ponieważ m==missVal zwraca matrycy logicznej (TRUE/FALSE) wartości. rowSums konwertuje TRUE do 1 i FALSE do 0, więc w tym przypadku możemy poznać wszystkie kolumny są 4 ilekroć rowSums powraca 11.

2

znalazłem to rozwiązanie gdzie indziej i jestem wklejając je tutaj używając kodu Andrie do generowania początkowy zestaw danych.

najpierw wygenerować zestaw danych:

set.seed(123) 
m <- matrix(sample(1:4, 30, prob=c(0.3, 0.3, 0.3, 0.1), replace=TRUE), ncol=6) 
m[4, ] <- rep(4, 6) 
m[m==4] <- NA 
m 

Oto intial zestaw danych:

1 1 NA 2 2 2 
2 3 3 1 2 3 
3 2 2 1 2 3 
NA NA NA NA NA NA 
NA 3 1 NA 2 1 

Teraz usunąć wiersze, które zawierają tylko brakujące obserwacje:

m[rowSums(is.na(m))<ncol(m),] 

Oto wynik:

1 1 NA 2 2 2 
2 3 3 1 2 3 
3 2 2 1 2 3 
NA 3 1 NA 2 1 
2

Korzystanie z data.table dla zwiększenia wydajności pamięci. Rozwiązanie tworzące is.na(x) tworzy zestaw danych tak duży, jak oryginał, a zatem jest nieefektywny.

library(data.table) 
DT <- as.data.table(m) 
missing_value <- 4 
missing <- as.data.table(setNames(as.list(rep(4, length(DT)), names(DT)) 
setkeyv(DT, names(DT)) 
setkey(missing, names(DT)) 

DT[-DT[(missing),which=T]] 

zarówno ten i @ rozwiązania JoshuaUlrich są szybko dla dużych danych

set.seed(21) 
m <- matrix(sample(1:6, 1100000, replace=TRUE), ncol=11) 
missVal <- 4 
missing_rows <- sample(100000, 53) 
m[missing_rows, ] <- rep(missVal, 11) 

DT <- as.data.table(m) 
setkeyv(DT, names(DT)) 
missing <- setNames(as.list(rep(missVal, 11)), names(DT)) 

system.time({DT1 <- DT[-DT[missing,which=T]]}) 
## user system elapsed 
## 0.02 0.00 0.01 
system.time({m1 <- m[ rowSums((m==missVal)) != NCOL(m), ]}) 
## user system elapsed 
## 0.02 0.02 0.03 
+1

Zachowaj ostrożność używając 'T' /' F' zamiast 'TRUE' /' FALSE', ponieważ 'T' i' F' mogą być ponownie zdefiniowane. –

Powiązane problemy