Может ли оператор «c» использоваться вместе с оператором «который»?

#r #data-manipulation

Вопрос:

Я использую язык программирования R. Мне интересно посмотреть, можно ли использовать оператор «c» вместе с оператором «which» в R. Например, рассмотрим следующий код (var1 и var2 являются «факторными» переменными):

 my_file   var1 var2 1 A AA 2 B CC 3 D CC 4 C AA 5 A BB  ouput lt;- my_file[which(my_file$var1 == c("A", "B", "C") amp; my_file$var2 !== c("AA", "CC")), ]  

Но это, похоже, не работает.

Я могу выполнить каждое из этих условий индивидуально, например

 output lt;- my_file[which(my_file$var1 == "A" | my_file$var1 == "B" | my_file$var1 == "C"), ] output1 lt;- output[which(output$var2 == "AA" | output$var2 == "CC" ), ]  

Но я хотел бы запустить их в более «компактной» форме, например:

 ouput lt;- my_file[which(my_file$var1 == c("A", "B", "C") amp; my_file$var2 !== c("AA", "CC")), ]  

Может кто-нибудь, пожалуйста, сказать мне, что я делаю не так?

Спасибо

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

1. Используйте %in% вместо == . Возможно, более простым способом было бы использовать filter функцию from dplyr вместо long which… .

2. Остерегайтесь NA ,хотя, так как, например NA %in% "A" , дает FALSE и нет NA !

Ответ №1:

Когда вы сравниваете my_file$var1 == c("A", "B", "C") , сравнение будет происходить поэлементно, но поскольку они разной длины, более короткие будут повторяться (с предупреждением, потому что повторение неполное.
c("A", "B", "D", "C", "A") == c("A", "B", "C", "A", "B") давая: c(TRUE, TRUE, FALSE, FALSE, FALSE) , потом which обратится в c(1, 2) .
Причина, по которой это работает, когда вы используете одну букву за раз, заключается в том, что повторение одного элемента 5 раз my_file$var1 == "A" приводит к c("A", "B", "D", "C", "A") == c("A", "A", "A", "A", "A") ожидаемому результату и дает ожидаемый результат.

@дешен прав, вы должны использовать %в%
output lt;- my_file[which(my_file$var1 %in% c("A", "B", "C") amp; !my_file$var2 %in% c("AA", "CC")), ]

Ответ №2:

Как говорит @deschen в комментарии, вы должны использовать %in% , а не == . Вы также можете (1) избавиться от which() (логическая индексация работает здесь так же хорошо, как и индексация по позиции) и (2) использовать subset , чтобы избежать повторного ввода my_file .

 output lt;- subset(my_file, var1 %in% c("A", "B", "C") amp;   !(var2 %in% c("AA", "CC")))  

В качестве альтернативы, если вам нравится tidyverse, это будет:

 library(dplyr) output lt;- my_file %gt;% dplyr::filter(var1 %in% c("A", "B", "C"),  !(var2 %in% c("AA", "CC")))  

(условия filter() работы, разделенные запятыми, такие же, как amp; ).