Comment combiner plusieurs conditions pour sous-ensemble une trame de données en utilisant «OU»?

174

J'ai un data.frame dans R. Je veux essayer deux conditions différentes sur deux colonnes différentes, mais je veux que ces conditions soient inclusives. Par conséquent, je voudrais utiliser "OU" pour combiner les conditions. J'ai déjà utilisé la syntaxe suivante avec beaucoup de succès lorsque je voulais utiliser la condition "ET".

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

Mais je ne sais pas comment utiliser un «OU» dans ce qui précède.

Sam
la source

Réponses:

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

Une solution alternative qui imite le comportement de cette fonction et serait plus appropriée pour l'inclusion dans un corps de fonction:

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

Certaines personnes critiquent l'utilisation de whichcomme non nécessaire, mais cela empêche les NAvaleurs de rejeter des résultats indésirables. L'équivalent (.ie ne renvoyant pas de lignes NA pour les NA en V1 ou V2) aux deux options présentées ci-dessus sans le whichserait:

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

Remarque: je tiens à remercier le contributeur anonyme qui a tenté de corriger l'erreur dans le code immédiatement ci-dessus, un correctif qui a été rejeté par les modérateurs. Il y avait en fait une erreur supplémentaire que j'ai remarquée en corrigeant la première. La clause conditionnelle qui vérifie les valeurs NA doit être la première si elle doit être traitée comme je l'avais prévu, puisque ...

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

L'ordre des arguments peut avoir une importance lors de l'utilisation de «&».

IRTFM
la source
1
C'est la question la plus votée, puis on trouve: stackoverflow.com/questions/9860090/…
PatrickT
1
L'avantage est la compacité et la facilité de compréhension. L'inconvénient est le manque d'utilité dans les tâches de création de fonctions. Si l'on veut reproduire cela avec, [il faut encapsuler whichou utiliser des !is.nacontraintes supplémentaires .
IRTFM
Le «qui» est-il obligatoire et sinon pourquoi l'utilisez-vous?
Cleb
1
Ce n'est pas "obligatoire", mais vous pouvez obtenir un résultat différent si vous omettez le which. Si les deux V1 et V2 sont NA, vous obtiendrez une ligne de NA à cette position si vous omettiez le which. Je travaille avec de grands ensembles de données et même un pourcentage relativement faible de NA remplira vraiment mon écran avec une sortie indésirable. Certaines personnes pensent que c'est une fonctionnalité. Je ne.
IRTFM
comment inclure un appel à greplou grepavec ceci pour faire également une correspondance de modèle pour les lignes souhaitées, en plus de ces conditions?
user5359531
31

Vous recherchez "|." Voir http://cran.r-project.org/doc/manuals/R-intro.html#Logical-vectors

my.data.frame <- data[(data$V1 > 2) | (data$V2 < 4), ]
ncray
la source
Ce n'est PAS robuste à l'existence de NAs dans un dataframe: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

Dans un souci d'exhaustivité, nous pouvons utiliser les opérateurs [et [[:

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

Plusieurs options

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 est équivalent à df [["name", exact = FALSE]]

Utilisation dplyr:

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

Utilisation sqldf:

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

Sortie pour les options ci-dessus:

          v1 v2
1 0.26550866  a
2 0.37212390  b
3 0.20168193  e
4 0.94467527  g
5 0.06178627  j
mpalanco
la source
1
comment feriez-vous cela pour 1 condition AND et 3 conditions OR contingentes, par exemple: my.data.frame <- data [data $ V3> 10 & ((data $ V1> 2) | (data $ V2 <4) | (données V4 $ <5),] Quand je fais cela , il ne fonctionne pas.
R Guru
1
Hou la la! Le sqldfpaquet est trop bon. Très pratique surtout quand subset()
ça