Seleccionar filas de una matriz que cumplan una condición

144

En R con una matriz:

     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

Quiero extraer la submatriz cuyas filas tienen la columna tres = 11. Es decir:

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

Quiero hacer esto sin bucles. Soy nuevo en R, por lo que esto probablemente sea muy obvio, pero la documentación a menudo es un tanto breve.

peter2108
fuente
44
La idea básica en cada respuesta es que si tiene un vector / matriz lógica (VERDADERO y FALSO) de la misma longitud que algún índice, seleccionará solo los casos que sean VERDADEROS. Ejecute los códigos entre [ ]las respuestas y verá esto más claramente.
Sacha Epskamp

Respuestas:

160

Esto es más fácil de hacer si convierte su matriz en un marco de datos usando as.data.frame (). En ese caso, las respuestas anteriores (usando el subconjunto o m $ tres) funcionarán, de lo contrario no lo harán.

Para realizar la operación en una matriz , puede definir una columna por su nombre:

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

O por número:

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

Tenga en cuenta que si solo coincide una fila, el resultado es un vector entero, no una matriz.

neilfws
fuente
19
si necesita mantener la matriz, entonces hágalom[m[,3] == 11,,drop=FALSE]
Joris Meys
@neilfws ¿Cuál será la solución si quiero definir algunos valores para un rango de columnas? Por ejemplo df <- df[!which(df$ARID3A:df$YY1 == "U"),], aquí Quiero eliminar esas filas de mi df, donde una serie de columnas (arid3a: YY1) contiene el valor T .
Novato
¿Cómo funciona esto si no desea especificar los nombres de las columnas pero desea trabajar sobre todas las columnas de la matriz?
user5359531
Hola @neilfws, ¿cómo puedes agregar una declaración && a esta? ¿Necesito obtener dos valores de columnas al mismo tiempo?
depuración XD
28
m <- matrix(1:20, ncol = 4) 
colnames(m) <- letters[1:4]

El siguiente comando seleccionará la primera fila de la matriz anterior.

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

Y esto seleccionará los últimos tres.

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

El resultado será una matriz en ambos casos. Si desea utilizar nombres de columna para seleccionar columnas, lo mejor sería convertirlo en un marco de datos con

mf <- data.frame(m)

Entonces puedes seleccionar con

mf[ mf$a == 16, ]

O bien, puede usar el comando de subconjunto.

Juan
fuente
21

Elegiré un enfoque simple usando el paquete dplyr.

Si el marco de datos son datos.

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

Subconjunto es una función muy lenta, y personalmente me parece inútil.

Asumo que tiene una hoja.de.datos, matriz, matriz de llamada Matcon A, B, Ccomo nombres de columna; entonces todo lo que necesitas hacer es:

  • En el caso de una condición en una columna, digamos la columna A

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

En el caso de múltiples condiciones en diferentes columnas, puede crear una variable ficticia. Supongamos que las condiciones son A = 10, B = 5y C > 2, entonces tenemos:

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

Al probar la ventaja de velocidad con system.time, el whichmétodo es 10 veces más rápido que el subsetmétodo.

Mohamad Elmasri
fuente
6

Si se llama a su matriz m, simplemente use:

R> m[m$three == 11, ]
juba
fuente
@juba ¿Cuál será la solución si quiero definir algunos valores para un rango de columnas? por ejemplo df <- df[!which(df$ARID3A:df$YY1 == "U"),], aquí quiero eliminar esas filas de mi df donde un rango de columnas (ARID3A: YY1) contiene el valorU
Newbie
0

Si el conjunto de datos se denomina datos, todas las filas que cumplan una condición en la que el valor de la columna 'pm2.5'> 300 pueda ser recibido por -

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

Anvita Shukla
fuente