2016-04-26 44 views
6

mam następujące dataframe (s)usuwanie zarówno wiersza i kolumny częściowego wartości NA

s<-read.table(text = "V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 
    1 0 62 64 44 NA 55 81 66 57 53 
    2 0 0 65 50 NA 56 79 69 52 55 
    3 0 0 0 57 NA 62 84 76 65 59 
    4 0 0 0 0 NA 30 70 61 41 36 
    5 0 0 0 0 NA NA NA NA NA NA 
    6 0 0 0 0 0 0 66 63 51 44 
    7 0 0 0 0 0 0 0 80 72 72 
    8 0 0 0 0 0 0 0 0 68 64 
    9 0 0 0 0 0 0 0 0 0 47 
    10 0 0 0 0 0 0 0 0 0 0 ", header = TRUE) 

Jak widać wiersz 5 i kolumnę 5, w tym przypadku zawiera tylko NA i 0 wartości. Chciałbym je pominąć i zachować kolejność linii i kolumn. Może być więcej kolumn i wierszy w tym samym wzorze i chciałbym zrobić to samo. Rozmiar ramki danych może zostać zmieniony. Efektem końcowym będzie:

V1 V2 V3 V4 V6 V7 V8 V9 V10 
1 0 62 64 44 55 81 66 57 53 
2 0 0 65 50 56 79 69 52 55 
3 0 0 0 57 62 84 76 65 59 
4 0 0 0 0 30 70 61 41 36 
6 0 0 0 0 0 66 63 51 44 
7 0 0 0 0 0 0 80 72 72 
8 0 0 0 0 0 0 0 68 64 
9 0 0 0 0 0 0 0 0 47 
10 0 0 0 0 0 0 0 0 0 

Czy istnieje sposób, aby uzyskać pominięto wiersza i numer kolumny (w tym przypadku 5), jak również?

+1

więc jaki jest minimalny nr NA, który uzasadniałby dumping wiersza/kolumny. Czy wszystkie wartości inne niż NA muszą wynosić 0? –

+0

Jak widać, jest to macierz górnego trójkąta. W każdym przypadku NA będzie dla wierszy: od kolumny numer wiersza do ostatniej kolumny (koniec). I dla tego samego numeru kolumny: od pierwszego wiersza do tego samego numeru wiersza (5 w tym przykładzie) – Avi

+0

Jest to prawdopodobnie oczywiste, ale: należy użyć macierzy, a nie danych.frame. – Frank

Odpowiedz

3

Możemy spróbować

v1 <- colSums(is.na(s)) 
v2 <- colSums(s==0, na.rm=TRUE) 
j1 <- !(v1>0 & (v1+v2)==nrow(s) & v2 >0) 

v3 <- rowSums(is.na(s)) 
v4 <- rowSums(s==0, na.rm=TRUE) 
i1 <- !(v3>0 & (v3+v4)==ncol(s) & v3 >0) 
s[i1, j1] 
# V1 V2 V3 V4 V6 V7 V8 V9 V10 
#1 0 62 64 44 55 81 66 57 53 
#2 0 0 65 50 56 79 69 52 55 
#3 0 0 0 57 62 84 76 65 59 
#4 0 0 0 0 30 70 61 41 36 
#6 0 0 0 0 0 66 63 51 44 
#7 0 0 0 0 0 0 80 72 72 
#8 0 0 0 0 0 0 0 68 64 
#9 0 0 0 0 0 0 0 0 47 
#10 0 0 0 0 0 0 0 0 0 

Załóżmy, że jeśli zmieniamy jedną z wartości w 's'

s$V7[3] <- NA 

Uruchamiając powyższy kod, wyjście będzie

# V1 V2 V3 V4 V6 V7 V8 V9 V10 
#1 0 62 64 44 55 81 66 57 53 
#2 0 0 65 50 56 79 69 52 55 
#3 0 0 0 57 62 NA 76 65 59 
#4 0 0 0 0 30 70 61 41 36 
#6 0 0 0 0 0 66 63 51 44 
#7 0 0 0 0 0 0 80 72 72 
#8 0 0 0 0 0 0 0 68 64 
#9 0 0 0 0 0 0 0 0 47 
#10 0 0 0 0 0 0 0 0 0 

UWAGA: Warunek OP to zawiera tylko wartości NA i 0. Chciałbym pominąć je

1

Można spróbować wykonać następujące czynności:

myRowSums <- rowSums(is.na(s) | s == 0) 
myColSums <- colSums(is.na(s) | s == 0) 

sSmall <- s[which(myRowSums != ncol(s)), which(myColSums != nrow(s))] 

Działa na poniższym zbiorze odrzucać wszystkie kolumny i wiersze, które są w całości zbudowane z 0s i NAS.

s <- data.frame(a=c(0, rnorm(5), 0), b=c(0, rnorm(2), NA, NA,1, NA), c=c(rep(c(0,NA), 3), 0)) 
+1

try 'sSmall <- s [myRowSums! = Ncol (s), myColSums! = Nrow (s)]' –

+0

Dzięki @SerbanTanasa. musiałem przepracować kilka literówek. – lmo

4

Musisz określić więcej, kiedy dokładnie chcesz upuścić. W tym przypadku wygląda na matrycy na jednej stronie i przekątnej zawsze jest 0.

Jednak w ogóle, to co używam

s[!rowSums(is.na(s))>1,!colSums(is.na(s))>1] 

Zważywszy 0 na

s[!rowSums(is.na(s)|s==0)>9,!colSums(is.na(s)|s==0)>9] 
3

ja jechałem zasugerować:

sclean <- s[rowSums(s == 0|is.na(s)) != ncol(s) | (rowSums(s == 0, na.rm=TRUE) == ncol(s)), 
     colSums(s == 0|is.na(s))!= nrow(s) | colSums(s == 0, na.rm=TRUE) == nrow(s)] 
+0

Nie sądzę, że jest to poprawne, ponieważ odpowiedź jest oparta na wartości NA większej niż 1. Może mieć więcej niż jedną NA z nie-NA (inną niż 0s). Na przykład, jeśli wykonamy 's $ V7 [3] <- NA', to pomija tę kolumnę, podczas gdy moje rozwiązanie ją przechowuje. – akrun

+1

@Avi Dodano warunek zachowania 0 kolumn. –

+0

@akrun, moje rozwiązanie wydaje się zachować v7 w teście. –