#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, как и?"||"
. Дело в том, что эти операторы и некоторые другие конструкции необходимо заключать в кавычки . Следовательно, я удалил предложения из вашего ответа.