как лучше сравнить формулы? - PullRequest
4 голосов
/ 28 марта 2019

Я бы хотел иметь возможность сравнить две формулы. Я задаюсь вопросом о преимуществах / недостатках / ловушках использования identical(), == или равенстве устаревших формул.

Рассмотрим, например,

xx <- ~0
environment(xx) <- new.env()
  • xx == ~0 возвращает TRUE
  • identical(xx, ~0) и identical(xx, ~0, ignore.environment=TRUE) return FALSE (аргумент ignore.environment применяется только при сравнении замыканий )
  • deparse(xx) == "~0" возвращает TRUE (но увольнение почти всегда плохая идея ...)

Чтобы попытаться прояснить ситуацию, я хочу, чтобы формулы были семантически эквивалентными; Меня не волнует их окружение. Было бы бонусом иметь возможность расширять формулы и игнорировать порядок терминов (например, ~a*b и ~b+a+a:b были бы эквивалентны), но это слишком большая кроличья нора, о которой стоит беспокоиться. Я согласен на то, что ~a+b и ~b+a не эквивалентны, если ~a+b (среда 1) и ~a+b (среда 2) одинаковы.

Мне пришло в голову написать функцию сравнения, которая заменяет среду обоих значений на emptyenv(), затем используя identical(), но это выглядело запутанным.

Есть ли крайние случаи / причины, по которым я не должен просто использовать == здесь?

1 Ответ

1 голос
/ 01 апреля 2019

Когда identical возвращает FALSE Я всегда пытаюсь all.equal, это гораздо менее строго. Цитирую свою справочную страницу:

all.equal(x, y) - это утилита для сравнения объектов R x и y тестирование «почти равенство». Если они разные, сравнение еще сделано в некоторой степени, и отчет о различиях возвращается.

xx <- ~0
environment(xx) <- new.env()

all.equal(xx, ~0)
#[1] TRUE

Но в if утверждениях это не должно использоваться как есть, правильный путь будет isTRUE(all.equal(.)). Опять из документации:

Не используйте all.equal напрямую в выражениях if - либо используйте isTRUE(all.equal(....)) или identical, если необходимо.

isTRUE(all.equal(xx, ~0))
#[1] TRUE
...