Почему в R grep и !grep логически не согласованы, когда grepl и !grepl логически непротиворечивы?

Функции R grep и !grep (НЕ grep) логически не согласованы; в отличие от grepl и !grepl (НЕ grepl), которые логически непротиворечивы.

grepl возвращает логический вектор, длина которого равна количеству искомых элементов. Например, если цель найдена в элементах 2 и 3 вектора из 5 элементов, возвращается следующее:

FALSE TRUE TRUE FALSE FALSE 

Если grepl заменить на !grepl, то возвращается "противоположный" логический результат:

TRUE FALSE FALSE TRUE TRUE 

grep, с другой стороны, возвращает вектор двух позиций найденных элементов: 2 3

Что возвращает !grep в том же сценарии? Логически он должен вернуть 1 4 5, вместо этого он возвращает FALSE FALSE. Как это может быть логически непротиворечивым возвращаемым значением? Кто-нибудь может объяснить?


person Charlie T    schedule 09.07.2016    source источник
comment
Поскольку grep возвращает вектор 0+ из integers, оператор ! (инверсия логики) для них не определен. Можете ли вы сказать мне с уверенностью, что означает invert_logic 5:7? (Если вы знаете длину вектора, вы можете вывести 1:4,8:n, но это самонадеянно.) Поскольку grepl возвращает вектор 0+ из logicals, имеет смысл сказать invert_logic c(T,T,F,T), и поскольку вы индексируете вектор с той же длиной вектор логических (инвертированный или иной), вы молодец. (Кстати: letters[ -grep("[f-h]", letters ] эффективно инвертирует.)   -  person r2evans    schedule 09.07.2016
comment
Попробуйте grep(..., invert = TRUE). Я думаю, это то, что вы хотите.   -  person Rich Scriven    schedule 09.07.2016
comment
1) grep возвращает индексы, соответствующие шаблону, а grepl возвращает логический вектор; 2) оператор ! приводит свой аргумент к logical. Попробуйте, например, !c(0,2,4), и вы увидите, что это эквивалентно !as.logical(c(0,2,4)); 3) проверьте аргумент invert grep.   -  person nicola    schedule 09.07.2016
comment
@ r2evans оператор ! (обратная логика) не определен для целого числа, это неверно. Вы можете использовать ! на векторах integer и numeric.   -  person nicola    schedule 09.07.2016
comment
Хорошо, я соглашусь с этим и возражу, что ! 5:7 получение F,F,F противоречит здравому смыслу, если вы не думаете, что 0 и FALSE эквивалентны. Спасибо за исправление (вы абсолютно правы), и это еще раз подчеркивает, почему это не будет работать (и, по общему признанию, возможно, некоторое несоответствие в том, как R и другие языки преобразуют типы в логические значения и из них).   -  person r2evans    schedule 09.07.2016
comment
@ r2evans Не понимаю, почему пример !5:7 нелогичен и о каких несоответствиях вы говорите. 0 — это FALSE, а любое другое число — это TRUE при принуждении к logical, вот и все.   -  person nicola    schedule 09.07.2016
comment
В контексте OP я сделал вывод, что ожидание ! grep(...) состоит в том, чтобы выбрать противоположные индексы, а не превращать все числа в FALSE. (Я часто (аб) использую условные выражения, такие как if (length(x)) { ... }, подразумевая, что ненулевое число — это TRUE, а 0 — это FALSE.) Вы правы, @nicola, и тем, кто изучает использование grep{,l}, просто нужно изучить соответствующие варианты использования. .   -  person r2evans    schedule 09.07.2016
comment
@ r2evans Я понял. ОП должен понимать, что !grep - это не функция (как они, кажется, подразумевают), а две функции, и оператор ! применяется к результату, полученному grep, и не меняет поведение из grep.   -  person nicola    schedule 09.07.2016


Ответы (2)


Вы ищете аргумент invert для grep().

От help(grep) в разделе Аргументы:

инвертировать - логично. Если TRUE вернуть индексы или значения для элементов, которые не совпадают.

Похоже, именно то, что вы хотите. Давайте посмотрим пример.

x <- c("ab", "cd", "bc", "def", "abc")

grep("b", x)
# [1] 1 3 5
grep("b", x, invert=TRUE)
# [1] 2 4
person Rich Scriven    schedule 09.07.2016

grep(value = FALSE) — возвращает вектор индексов элементов x, которые дали совпадение.

grepl возвращает логический вектор (совпадает или нет для каждого элемента x).

grep vs grepl в R

person user3237667    schedule 09.07.2016