Como combinar várias condições para subconjunto de um quadro de dados usando "OU"?

174

Eu tenho um data.frame em R. Quero tentar duas condições diferentes em duas colunas diferentes, mas quero que essas condições sejam inclusivas. Portanto, eu gostaria de usar "OR" para combinar as condições. Eu usei a seguinte sintaxe antes com muito sucesso quando queria usar a condição "AND".

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

Mas não sei como usar um 'OU' acima.

Sam
fonte

Respostas:

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

Uma solução alternativa que imita o comportamento dessa função e seria mais apropriada para inclusão dentro de um corpo da função:

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

Algumas pessoas criticam o uso whichcomo não necessário, mas isso impede que os NAvalores retornem resultados indesejados. O equivalente (.ie, não retornando linhas de NA para nenhum NA de V1 ou V2) às duas opções demonstradas acima sem a opção whichseria:

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

Nota: quero agradecer ao colaborador anônimo que tentou corrigir o erro no código imediatamente acima, uma correção que foi rejeitada pelos moderadores. Na verdade, houve um erro adicional que eu notei quando corrigi o primeiro. A cláusula condicional que verifica os valores de NA precisa ser a primeira a ser tratada como pretendia, pois ...

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

A ordem dos argumentos pode ser importante ao usar '& ".

IRTFM
fonte
1
Esta é a maior questão votado e, em seguida, encontra-se: stackoverflow.com/questions/9860090/...
PatrickT
1
A vantagem é compacta e fácil de entender. A desvantagem é a falta de utilidade nas tarefas de criação de funções. Se alguém quiser replicar isso, [precisará envolver whichou usar !is.narestrições adicionais .
IRTFM
O 'what' é obrigatório e, se não, por que você o usa?
cleb
1
Não é "obrigatório", mas você pode obter um resultado diferente se deixar de fora o which. Se V1 e V2 forem NA, você obterá uma fila de NA nessa posição se deixar de fora o which. Eu trabalho com grandes conjuntos de dados e até uma porcentagem relativamente pequena de NA realmente preenche minha tela com lixo eletrônico. Algumas pessoas pensam que isso é um recurso. Eu não.
IRTFM
como você inclui uma chamada para isso greplou greptambém faz a correspondência de padrões para as linhas desejadas, além desses condicionais?
user5359531
31

Você está procurando "|." Consulte http://cran.r-project.org/doc/manuals/R-intro.html#Logical-vectors

my.data.frame <- data[(data$V1 > 2) | (data$V2 < 4), ]
ncray
fonte
Este não é robusta para a existência de NAs em uma trama de dados: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

Por uma questão de integridade, podemos usar os operadores [e [[:

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

Várias opções

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 é equivalente a df [["name", exato = FALSE]]

Usando dplyr:

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

Usando sqldf:

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

Saída para as opções acima:

          v1 v2
1 0.26550866  a
2 0.37212390  b
3 0.20168193  e
4 0.94467527  g
5 0.06178627  j
mpalanco
fonte
1
como você faria isso para as condições 1 AND e 3 OR contingentes, por exemplo: my.data.frame <- data [data $ V3> 10 & ((dados $ V1> 2) | (dados $ V2 <4) | (dados $ V4 <5),] Quando eu fizer isso ele não funciona.
R Guru
1
Uau! O sqldfpacote é muito bom. Muito útil especialmente quando subset()fica um pouco :) dolorosa
Dawny33