2011-08-25 19 views
5

Ho un grande set di dati con 11 colonne e 100000 righe (per esempio) in cui ho i valori 1,2,3,4. Dove 4 è un valore mancante. Alcune file sono completamente mancanti. cioè 4 in tutte le 11 colonne. Ad esempioCome rimuovere una riga che contiene solo valori mancanti in R?

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

Ora quello che mi serve è rimuovere solo quelle righe che mancano completamente. In parole semplici, voglio mantenere le righe con valore mancante inferiore a 11. Ho usato na.omit, ma nel mio caso non funziona.

Grazie in anticipo.

+0

Come si fa questo probabilmente dipenderà da informazioni che non ci avete fornito. Si tratta di un frame di dati o una matrice? I valori sono memorizzati come numeri interi o caratteri? Prova a modificare la tua domanda con l'output eseguendo 'str (head (foo))' dove 'foo' sono i tuoi dati. – joran

risposta

2

Un modo davvero veloce sarebbe utilizzare un po 'di matematica. Assumendo che il dataframe si chiama datf

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

(lavora per una matrice troppo)

+2

Non ti darò un meno 1, ma questo tipo di approccio è molto pericoloso. Funziona per questo caso specifico, ma cosa succede se aggiungi/cancella una colonna? Cerca sempre di risolvere i problemi in modo solido. – Andrie

+1

Questo non funzionerà perché una riga può sommare a 44 senza che tutti gli elementi siano 4 (ad esempio 'c (4,4,4,4,4,4,4,4,4,3,5)'). –

+0

note domanda ... i valori possono essere solo 1, 2, 3 o 4 in questo set di dati. – John

1

Qualcosa del genere dovrebbe fare il trucco (e dovrebbe funzionare sia per le matrici e le 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") 
})) 

Ora si può semplicemente fare

newac<-ac[-rowsToRemove,] 
11

Forse la soluzione migliore è di utilizzare L'idioma di R per lavorare con i valori mancanti, o NA. Una volta che hai codificato i valori NA puoi lavorare con complete.cases per raggiungere facilmente il tuo obiettivo.

Creare alcuni dati di esempio con valori mancanti (cioè con il valore 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) 

sostituire tutti i valori uguali a 4 con 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 

ora è possibile utilizzare una serie di funzioni che trattare con i valori NA. Ad esempio, complete.cases tornerà solo, avete indovinato, i casi completi:

m[complete.cases(m), ] 

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

Per ulteriori informazioni, vedere ?complete.cases o ?na.fail nel pacchetto stats.

+0

Questo non è quello che viene chiesto. L'OP vuole rimuovere solo le righe che sono completamente mancanti. – Kenji

2

Questa è la soluzione più veloce che posso pensare. Userò dati di esempio simili a @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), ] 

L'ultima riga funziona perché m==missVal restituisce una matrice (TRUE/FALSE) valori logici. rowSums converte TRUE-1 e FALSE-0, quindi in questo caso sappiamo tutte le colonne sono 4 ogni volta rowSums rendimenti 11.

2

ho trovato questa soluzione altrove e sto incollandolo qui utilizzando il codice di Andrie per generare il set di dati iniziali.

Prima generare il set di dati:

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 

Ecco la intial set di dati:

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 

Ora rimuovere le righe che contengono solo osservazioni mancanti:

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

Ecco il risultato:

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

Utilizzo di data.table per l'efficienza della memoria. La soluzione che crea is.na(x) sta creando un set di dati grande quanto l'originale e quindi è inefficiente.

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]] 

sia questa e la soluzione di @ JoshuaUlrich sono veloci per dati di grandi dimensioni

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

State attenti a usare 'T' /' F' invece di 'TRUE' /' FALSE', poiché 'T' e' F' possono essere ridefiniti. –

Problemi correlati