Seleziona le righe di una matrice che soddisfano una condizione


144

In R con una matrice:

     one two three four
 [1,]   1   6    11   16
 [2,]   2   7    12   17
 [3,]   3   8    11   18
 [4,]   4   9    11   19
 [5,]   5  10    15   20

Voglio estrarre il sottomatrix le cui righe hanno la colonna tre = 11. Cioè:

      one two three four
 [1,]   1   6    11   16
 [3,]   3   8    11   18
 [4,]   4   9    11   19

Voglio farlo senza loop. Sono nuovo di R, quindi questo è probabilmente molto ovvio, ma la documentazione è spesso piuttosto concisa.


4
L'idea di base in ogni risposta è che se si dispone di un vettore / matrice logici (TRUE e FALSE) della stessa lunghezza di alcuni indici, si selezioneranno solo i casi TRUE. Esegui i codici tra [ ]nelle risposte e lo vedrai più chiaramente.
Sacha Epskamp,

Risposte:


160

Questo è più facile da fare se converti la tua matrice in un frame di dati usando as.data.frame (). In tal caso, le risposte precedenti (utilizzando un sottoinsieme o m $ tre) funzioneranno, altrimenti non funzioneranno.

Per eseguire l'operazione su una matrice , è possibile definire una colonna per nome:

m[m[, "three"] == 11,]

O per numero:

m[m[,3] == 11,]

Nota che se solo una riga corrisponde, il risultato è un vettore intero, non una matrice.


19
se hai bisogno di mantenere la matrice, allora fallom[m[,3] == 11,,drop=FALSE]
Joris Meys il

@neilfws Quale sarà la soluzione se voglio definire alcuni valori per una serie di colonne. per esempio df <- df[!which(df$ARID3A:df$YY1 == "U"),], qui voglio per rimuovere le righe dal mio df, dove una serie di colonne (ARID3A: YY1) contiene il valore U .
Principiante

Come funziona se non vuoi affatto specificare i nomi delle colonne ma vuoi lavorare su tutte le colonne della matrice?
user5359531

Ehi @neilfws, come puoi aggiungere un'istruzione && a questa? Devo ottenere due valori di colonne contemporaneamente?
debug di XD il

28
m <- matrix(1:20, ncol = 4) 
colnames(m) <- letters[1:4]

Il seguente comando selezionerà la prima riga della matrice sopra.

subset(m, m[,4] == 16)

E questo selezionerà gli ultimi tre.

subset(m, m[,4] > 17)

Il risultato sarà una matrice in entrambi i casi. Se si desidera utilizzare i nomi di colonna per selezionare le colonne, sarebbe meglio convertirlo in un frame di dati con

mf <- data.frame(m)

Quindi puoi selezionare con

mf[ mf$a == 16, ]

In alternativa, è possibile utilizzare il comando subset.


21

Sceglierò un approccio semplice usando il pacchetto dplyr.

Se il frame di dati è data.

library(dplyr)
result <- filter(data, three == 11)

11

Il sottoinsieme è una funzione molto lenta e personalmente lo trovo inutile.

Suppongo di avere un data.frame, un array a matrice chiamato Matcon A, B, Ccome nomi di colonna; allora tutto ciò che devi fare è:

  • Nel caso di una condizione su una colonna, diciamo la colonna A

    Mat[which(Mat[,'A'] == 10), ]

Nel caso di più condizioni su colonne diverse, è possibile creare una variabile fittizia. Supponiamo che le condizioni siano A = 10, B = 5e C > 2quindi abbiamo:

    aux = which(Mat[,'A'] == 10)
    aux = aux[which(Mat[aux,'B'] == 5)]
    aux = aux[which(Mat[aux,'C'] > 2)]
    Mat[aux, ]

Testando il vantaggio della velocità con system.time, il whichmetodo è 10 volte più veloce del subsetmetodo.


6

Se viene chiamata la tua matrice m, basta usare:

R> m[m$three == 11, ]

@juba Quale sarà la soluzione se voglio definire alcuni valori per un intervallo di colonne. per esempio df <- df[!which(df$ARID3A:df$YY1 == "U"),], qui voglio rimuovere quelle righe dal mio df in cui un intervallo di colonne (ARID3A: YY1) contiene il valoreU
Newbie

0

Se il set di dati viene chiamato dati, tutte le righe che soddisfano una condizione in cui il valore della colonna 'pm2.5'> 300 può essere ricevuto da -

data [data ['pm2.5']> 300,]

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.