Использование нескольких критериев в подмножестве функций и логических операторов - PullRequest
16 голосов
/ 26 апреля 2011

Если я хочу выбрать подмножество данных в R, я могу использовать функцию подмножества.Я хотел основывать анализ на данных, которые соответствовали одному из нескольких критериев, например, что определенная переменная была 1, 2 или 3. Я пытался

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

Он всегда просто выбирал значения, которые соответствовалипервый из критериев, здесь 1. Я предположил, что он будет начинаться с 1, и если он оценивается как «ложный», он переходит к 2, а затем к 3, и если ни один из них не соответствует утверждению после == равно «ложь»"и если один из них совпадает, это" true ".

Я получил правильный результат, используя

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

Но я хотел бы иметь возможность выбирать данные с помощью логических операторов, поэтому: почему первый подход не сработал?

Ответы [ 2 ]

26 голосов
/ 26 апреля 2011

Правильный оператор здесь %in%.Вот пример с фиктивными данными:

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

, дающий:

> 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

Подмножество dat, где bf11 равно любому из набора 1,2,3, берется следующим образомиспользуя %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

Что касается того, почему ваш оригинал не работал, разбейте его, чтобы увидеть проблему.Посмотрите на то, что 1||2||3 оценивает:

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

, и вы получите то же самое, используя |.В результате вызов subset() будет возвращать только те строки, где bf11 было TRUE (или что-то, что оценивается как TRUE).

То, что вы могли бы написать, было бы примерно таким:

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

Что дает тот же результат, что и мой предыдущий subset() звонок.Дело в том, что вам нужна серия отдельных сравнений, а не серия опций.Но, как видите, %in% гораздо более полезен и менее многословен в таких обстоятельствах.Также обратите внимание, что я должен использовать |, поскольку я хочу сравнить каждый элемент bf11 с 1, 2 и 3 по очереди.Сравните:

> 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
5 голосов
/ 26 апреля 2011

Для вашего примера, я считаю, что должно работать следующее:

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

См. Примеры в ?subset. Просто чтобы продемонстрировать, более сложное логическое подмножество будет:

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

И, как указывает Чейз, %in% будет более эффективным в вашем примере:

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

Как и Чейз, убедитесь, что понимаете разницу между | и ||. Чтобы увидеть справочные страницы для операторов, используйте ?'||', где оператор указан в кавычках.

...