Использование нескольких критериев в функции подмножества и логических операторах

#r #subset #logical-operators #operator-precedence

#r #подмножество #логические операторы #оператор-приоритет

Вопрос:

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

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

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

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

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

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

Комментарии:

1. Взгляните на ? Страница справки по логике. || форма работает слева направо и проверяет только первый элемент в векторе. %in% также было бы полезно использовать оператор в этих ситуациях. поиск SO для [r] %in% должен быть поучительным.

2. @Chase || и | здесь бесполезны: 1||2||3 и 1|2|3 вычислять значение TRUE, чтобы подмножество включало только те, где bf11 было TRUE (или что-то, что оценивалось как TRUE). %in% здесь более чем полезно.

3. @Gavin — спасибо, что закончил мое предложение там — пришлось бежать на другую встречу.

4. То, что вы говорите «получил правильный результат», вероятно, пропускает несколько случаев, когда bf11 действительно равен 1, 2 или 3. %in% работает лучше всего, как говорит Гэвин Симпсон

Ответ №1:

Здесь находится правильный оператор %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
  

Комментарии:

1. Как я могу найти страницу справки о «% в%»? Я использовал?%в%, но это не сработало.

2. @kostia Процитируйте оператор: что-то вроде ?"%in%"

Ответ №2:

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

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

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

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

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

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

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

Комментарии:

1. ?'||' отлично работает в R, как и ?"||" . Дело в том, что эти операторы и некоторые другие конструкции необходимо заключать в кавычки . Следовательно, я удалил предложения из вашего ответа.