¿Cómo combinar múltiples condiciones para subconjugar un marco de datos usando "O"?

174

Tengo un data.frame en R. Quiero probar dos condiciones diferentes en dos columnas diferentes, pero quiero que estas condiciones sean inclusivas. Por lo tanto, me gustaría usar "O" para combinar las condiciones. He usado la siguiente sintaxis antes con mucho éxito cuando quería usar la condición "Y".

my.data.frame <- data[(data$V1 > 2) & (data$V2 < 4), ]

Pero no sé cómo usar un 'OR' en lo anterior.

Sam
fuente

Respuestas:

249
my.data.frame <- subset(data , V1 > 2 | V2 < 4)

Una solución alternativa que imita el comportamiento de esta función y sería más apropiada para su inclusión dentro del cuerpo de una función:

new.data <- data[ which( data$V1 > 2 | data$V2 < 4) , ]

Algunas personas critican el uso de whichcomo no necesario, pero impide que los NAvalores arrojen resultados no deseados. El equivalente (.ie no devolver filas de NA para ningún NA en V1 o V2) a las dos opciones demostradas anteriormente sin el whichsería:

 new.data <- data[ !is.na(data$V1 | data$V2) & ( data$V1 > 2 | data$V2 < 4)  , ]

Nota: Quiero agradecer al contribuyente anónimo que intentó corregir el error en el código inmediatamente anterior, una solución que fue rechazada por los moderadores. En realidad hubo un error adicional que noté cuando estaba corrigiendo el primero. La cláusula condicional que verifica los valores de NA debe ser primero si se va a manejar como pretendía, ya que ...

> NA & 1
[1] NA
> 0 & NA
[1] FALSE

El orden de los argumentos puede ser importante cuando se usa '& ".

IRTFM
fuente
1
Esta es la pregunta más votada y luego se encuentra: stackoverflow.com/questions/9860090/…
PatrickT
1
La ventaja es la compacidad y la facilidad de comprensión. La desventaja es la falta de utilidad en las tareas de creación de funciones. Si uno quiere replicar esto con [uno necesita envolver whicho usar !is.narestricciones adicionales .
IRTFM
¿Se requiere el 'cual'? Si no, ¿por qué lo usa?
Cleb
1
No es "obligatorio", pero puede obtener un resultado diferente si omite el which. Si tanto V1 como V2 son NA, obtendría una fila de NA en esa posición si omitiera el which. Trabajo con grandes conjuntos de datos e incluso un porcentaje relativamente pequeño de NA realmente llenará mi pantalla con resultados basura. Algunas personas piensan que esta es una característica. Yo no.
IRTFM
¿Cómo incluye una llamada a greplo grepcon esto para también hacer coincidir patrones para las filas deseadas, además de estos condicionales?
user5359531
31

Estás buscando "|". Ver http://cran.r-project.org/doc/manuals/R-intro.html#Logical-vectors

my.data.frame <- data[(data$V1 > 2) | (data$V2 < 4), ]
ncray
fuente
Esto NO es robusto para la existencia de NAs en un marco de datos:vc <- data.frame(duzey=factor(c("Y","O","Y","D","Y","Y","O"), levels=c("D","O","Y"), ordered=TRUE), cinsiyet=c("E","E","K",NA,"K","E","K"), yas=c(8,3,9,NA,7,NA,6), Not=c(NA,1,1,NA,NA,2,1)); vc; vc[vc$cinsiyet == "E" | vc$Not < 4,]; vc[vc$cinsiyet == "E" & vc$Not < 2,]
Erdogan CEVHER
17

Solo en aras de la integridad, podemos utilizar los operadores [y [[:

set.seed(1)
df <- data.frame(v1 = runif(10), v2 = letters[1:10])

Varias opciones

df[df[1] < 0.5 | df[2] == "g", ] 
df[df[[1]] < 0.5 | df[[2]] == "g", ] 
df[df["v1"] < 0.5 | df["v2"] == "g", ]

df $ name es equivalente a df [["nombre", exacto = FALSO]]

Utilizando dplyr:

library(dplyr)
filter(df, v1 < 0.5 | v2 == "g")

Utilizando sqldf:

library(sqldf)
sqldf('SELECT *
      FROM df 
      WHERE v1 < 0.5 OR v2 = "g"')

Salida para las opciones anteriores:

          v1 v2
1 0.26550866  a
2 0.37212390  b
3 0.20168193  e
4 0.94467527  g
5 0.06178627  j
mpalanco
fuente
1
¿cómo haría esto para la condición 1 AND y las condiciones 3 OR contingentes, por ejemplo: my.data.frame <- data [data $ V3> 10 & ((data $ V1> 2) | (data $ V2 <4) | (datos $ V4 <5),]. Cuando hago esto no funciona
R Guru
1
¡Guauu! El sqldfpaquete es muy bueno. Muy útil, especialmente cuando se subset()vuelve un poco doloroso :)
Dawny33