Неожиданное поведение при использовании -which() в R, когда поисковый термин не найден
Я использовал R which
функция для удаления строк из фрейма данных. Недавно я обнаружил, что если поисковый термин НЕ находится в data.frame, результатом будет пустой символ.
# 1: returns A-Q, S-Z (as expected)
LETTERS[-which(LETTERS == "R")]
# 2: returns "character(0)" (not what I would expect)
LETTERS[-which(LETTERS == "1")]
# 3: returns A-Z (expected)
LETTERS[which(LETTERS != "1")]
# 4: returns A-Q, S-Z (expected)
LETTERS[which(LETTERS != "R")]
Является ли второй пример ожидаемым поведением для -which()
когда поисковый термин не найден? Я уже переключил свой код на использование синтаксиса в примере 4, который кажется более безопасным, но мне просто любопытно.
3 ответа
Это известная ловушка. Когда ничто не соответствует логическому тесту, функция which возвращает numeric(0), а затем "[" ничего не возвращает вместо возврата всего, что ожидалось. Ты можешь использовать:
LETTERS[ ! LETTERS == "1" ]
LETTERS[ ! LETTERS %in% "1" ]
Есть еще один момент, о котором нужно знать, и именно он заставляет меня выбрать использование которого (). При использовании логической индексации значение NA, используемое внутри "[", вернет строку. Я вообще не хочу этого, поэтому я использую DFRM[ which(logical) ]
хотя это, кажется, беспокоит некоторых людей, которые говорят, что это не нужно. Я просто думаю, что они работают с небольшими наборами данных и нечасто сталкиваются с досадой, когда видят десятки тысяч бесполезных линий вывода, вызванных NA, на их консоли. Я никогда не использую отрицательную версию, хотя.
Из-за этого:
which(LETTERS == '-1')
## integer(0)
и это:
(1:2)[integer(0)]
integer(0)
Вместо #4 используйте это:
LETTERS[LETTERS != "R"]
В примере 2 which
возвращается integer(0)
(целочисленный вектор нулевой длины), потому что нет значений TRUE
, Отрицательный вектор нулевой длины (-integer(0)
) по-прежнему является вектором нулевой длины. Итак, вы по сути просите NULL
элемент LETTERS
, которого не существует