#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
функцию fromdplyr
вместо longwhich…
.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;
).