Відповідь
Зітхніть, мені знадобилося 45 хвилин, щоб знайти відповідь на це просте запитання. Відповідь:grepl(needle, haystack, fixed=TRUE)
# Correct
> grepl("1+2", "1+2", fixed=TRUE)
[1] TRUE
> grepl("1+2", "123+456", fixed=TRUE)
[1] FALSE
# Incorrect
> grepl("1+2", "1+2")
[1] FALSE
> grepl("1+2", "123+456")
[1] TRUE
Інтерпретація
grep
названий в честь Linux виконуваного файлу, який сам по собі є абревіатурою « G ЛОБАЛЬНИЕ R Регулярної E Xpression P ечаті», він буде читати рядки введення , а потім роздрукувати їх , якщо вони відповідали аргументам , які ви дали. "Глобальний" означав, що збіг може статися в будь-якому місці рядка введення, я поясню "Регулярне вираження" нижче, але ідея полягає в тому, що це розумніший спосіб зіставити рядок (R називає цього "символом", наприкладclass("abc")
) та "Друкувати" "тому що це програма командного рядка, випромінюючи висновок, це означає, що вона друкує у вихідний рядок.
Тепер grep
програма - це в основному фільтр, від рядків введення до ліній виводу. І здається, що Rgrep
функція аналогічно займе масив входів. З причин, які мені абсолютно невідомі (я почав грати з R лише годину тому), він повертає вектор індексів, які відповідають, а не список збігів.
Але повернемось до вашого первинного питання, що ми насправді хочемо - це знати, чи знайшли ми голку в стозі сіна, що є справжньою / хибною цінністю. Вони, мабуть, вирішили назвати цю функцію grepl
, як у "grep", але з " L ogical" зворотним значенням (вони називають істинні та хибні логічні значення, наприклад class(TRUE)
).
Отже, тепер ми знаємо, звідки пішла назва і що вона повинна робити. Повернемося до регулярних виразів. Аргументи, хоча вони є рядками, вони використовуються для побудови регулярних виразів (відтепер: регулярний вираз). Регекс - це спосіб зіставити рядок (якщо це визначення дратує вас, відпустіть його). Наприклад, регулярний вираз a
відповідає символу "a"
, регулярний вираз a*
відповідає символу "a"
0 або більше разів, а регулярний вираз a+
відповідає "a"
1 або більше разів. Отже, у наведеному вище прикладі голка, яку ми шукаємо 1+2
, коли вона розглядається як регулярний вираз, означає "один чи більше 1, за якими йде 2" ... але за нашим йде плюс!
Отже, якщо ви використовували grepl
без установки fixed
, ваші голки випадково були б стогами сіна, і це випадково спрацювало б досить часто, ми можемо бачити, що це працює навіть на прикладі ОП. Але це прихована помилка! Нам потрібно сказати, що вхід - це рядок, а не регулярний вираз, який, мабуть, якийfixed
є для чого. Чому виправлено? Немає жодної підказки, додайте закладку на цю відповідь б / с, ймовірно, вам доведеться переглянути її ще 5 разів, перш ніж ви запам'ятаєте її.
Кілька заключних думок
Чим краще ваш код, тим менше історії ви повинні знати, щоб мати сенс. Кожен аргумент може мати принаймні два цікавих значення (інакше це не повинно бути аргументом). Документи перераховують тут 9 аргументів, це означає, що є принаймні 2 ^ 9 = 512 способи викликати його, для цього потрібно багато роботи пишіть, тестуйте і запам’ятовуйте ... розв'яжіть такі функції (розділіть їх, усуньте залежності один від одного, рядкові речі відрізняються, ніж регекс-речі відрізняються від векторних речей). Деякі варіанти є також взаємовиключними, не дають користувачам невірних способів використання коду, тобто проблемне виклик має бути структурно безглуздим (наприклад, передача опції, яка не існує), а не логічно безглуздою (де потрібно видати попередження, щоб пояснити це). Поставте метафорично: заміна вхідних дверей у бік 10-го поверху на стіну краще, ніж підвісити табличку, яка застерігає від її використання, але або краща, ніж ні одна. В інтерфейсі функція визначає, як повинні виглядати аргументи, а не виклик (тому що виклик залежить від функції. Висновок про все, до чого кожен може хотіти зателефонувати) робить функцію залежною і від абонентів, і від цього типу циклічна залежність швидко засмітить систему і ніколи не забезпечить очікувані переваги). Будьте дуже обережні до вигідних типів, це недолік дизайну, який подобається Звідси випливає все, на що кожен може хотіти зателефонувати, робить функцію залежною від абонентів, і цей тип циклічної залежності швидко засмітить систему і ніколи не надасть переваг, які ви очікуєте). Будьте дуже обережні до вигідних типів, це недолік дизайну, який подобається Звідси випливає все, на що кожен може хотіти зателефонувати, робить функцію залежною від абонентів, і цей тип циклічної залежності швидко засмітить систему і ніколи не надасть переваг, які ви очікуєте). Будьте дуже обережні до вигідних типів, це недолік дизайну, який подобаєтьсяTRUE
і 0
і "abc"
всі вектори.
fixed=TRUE
, інакше ви трактуєте її як регулярний вимір замість рядка. Дивіться мою відповідь з жовтня 2016 року