web-dev-qa-db-fra.com

Utilisation de plusieurs critères dans la fonction de sous-ensemble et les opérateurs logiques

Si je veux sélectionner un sous-ensemble de données dans R, je peux utiliser la fonction de sous-ensemble. Je voulais baser une analyse sur des données qui correspondaient à l'un des quelques critères, par ex. qu'une certaine variable était soit 1, 2 ou 3. J'ai essayé

myNewDataFrame <- subset(bigfive, subset = (bigfive$bf11==(1||2||3)))

Il sélectionnait toujours simplement les valeurs qui correspondaient au premier des critères, ici 1. Mon hypothèse était qu'il commencerait par 1 et s'il est évalué à "faux", il passerait à 2 et à 3, et si aucune ne correspond l'instruction après == est "false" et si l'un d'eux correspond, c'est "true".

J'ai obtenu le bon résultat en utilisant

 newDataFrame <- subset(bigfive, subset = (bigfive$bf11==c(1,2,3)))

Mais je voudrais pouvoir sélectionner des données via des opérateurs logiques, alors: pourquoi la première approche n'a-t-elle pas fonctionné?

19
JanD

L'opérateur correct est %in% Ici. Voici un exemple avec des données factices:

set.seed(1)
dat <- data.frame(bf11 = sample(4, 10, replace = TRUE),
                  foo = runif(10))

donnant:

> head(dat)
  bf11       foo
1    2 0.2059746
2    2 0.1765568
3    3 0.6870228
4    4 0.3841037
5    1 0.7698414
6    4 0.4976992

Le sous-ensemble de datbf11 Est égal à l'un des ensembles 1,2,3 Est pris comme suit en utilisant %in%:

> subset(dat, subset = bf11 %in% c(1,2,3))
   bf11       foo
1     2 0.2059746
2     2 0.1765568
3     3 0.6870228
5     1 0.7698414
8     3 0.9919061
9     3 0.3800352
10    1 0.7774452

Quant à savoir pourquoi votre original n'a pas fonctionné, décomposez-le pour voir le problème. Regardez ce que 1||2||3 Évalue:

> 1 || 2 || 3
[1] TRUE

et vous obtiendriez la même chose en utilisant | à la place. Par conséquent, l'appel subset() ne retournerait que les lignes où bf11 Était TRUE (ou quelque chose évalué à TRUE).

Ce que vous auriez pu écrire aurait été quelque chose comme:

subset(dat, subset = bf11 == 1 | bf11 == 2 | bf11 == 3)

Ce qui donne le même résultat que mon précédent appel à subset(). Le fait est que vous avez besoin d'une série de comparaisons uniques, et non d'une comparaison d'une série d'options. Mais comme vous pouvez le voir, %in% Est beaucoup plus utile et moins verbeux dans de telles circonstances. Notez également que je dois utiliser | Car je veux comparer chaque élément de bf11 Avec 1, 2 Et 3, à son tour. Comparer:

> with(dat, bf11 == 1 || bf11 == 2)
[1] TRUE
> with(dat, bf11 == 1 | bf11 == 2)
 [1]  TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE
27
Gavin Simpson

Pour votre exemple, je pense que les éléments suivants devraient fonctionner:

myNewDataFrame <- subset(bigfive, subset = bf11 == 1 | bf11 == 2 | bf11 == 3)

Voir les exemples dans ?subset pour plus. Juste pour démontrer, un sous-ensemble logique plus compliqué serait:

data(airquality)
dat <- subset(airquality, subset = (Temp > 80 & Month > 5) | Ozone < 40)

Et comme le souligne Chase, %in% serait plus efficace dans votre exemple:

myNewDataFrame <- subset(bigfive, subset = bf11 %in% c(1, 2, 3))

Comme Chase le souligne également, assurez-vous de bien comprendre la différence entre | et ||. Pour afficher les pages d'aide pour les opérateurs, utilisez ?'||', où l'opérateur est cité.

5
jthetzel