Вы переназначаете == и! = IsTRUE (all.equal ())? - PullRequest
7 голосов
/ 05 октября 2011

A предыдущий пост побудил меня задать этот вопрос.Казалось бы, наилучшей практикой является переназначение == на isTRUE(all.equal())!= на !isTRUE(all.equal()). Мне интересно, если другие делают это на практике? Я только что понял, что использую == и != чтобы сделать числовое равенство во всей моей кодовой базе. Моей первой реакцией было то, что мне нужно сделать полную очистку и преобразовать в all.equal. Но на самом деле, каждый раз, когда я использую == и !=, я хочу проверить равенство (независимо от того,типа данных). На самом деле, я не уверен, что эти операции будут проверять другие, кроме равенства. Я уверен, что мне здесь не хватает какой-то концепции. Может кто-то просветить меня? Единственный аргумент, который я вижу против этого подхода, заключается в том, чтов некоторых случаях два неидентичных числа будут казаться идентичными из-за допустимого отклонения all.equal. Но нам говорят, что два фактически идентичных числа могут не пройти identical() из-за того, как они хранятся в памятиТак на самом деле какой смысл не по умолчанию all.equal?

1 Ответ

7 голосов
/ 06 октября 2011

Как намекал @joran, вы столкнетесь с проблемами с плавающей запятой с == и != практически на любом другом языке.Одним из важных аспектов их в R. является часть векторизации.

Было бы намного лучше определить новую функцию almostEqual, fuzzyEqual или аналогичную.К сожалению, такой базовой функции нет.all.equal не очень эффективен, так как обрабатывает все виды объектов и возвращает строку , описывающую разницу, когда в основном вы просто хотите TRUE или FALSE.

Вот примертакой функции.Он векторизован как ==.

almostEqual <- function(x, y, tolerance=1e-8) {
  diff <- abs(x - y)
  mag <- pmax( abs(x), abs(y) )
  ifelse( mag > tolerance, diff/mag <= tolerance, diff <= tolerance)
}

almostEqual(1, c(1+1e-8, 1+2e-8)) # [1]  TRUE FALSE

... он примерно в 2 раза быстрее, чем all.equal для скалярных значений, и намного быстрее с векторами.

x <- 1
y <- 1+1e-8
system.time(for(i in 1:1e4) almostEqual(x, y)) # 0.44 seconds
system.time(for(i in 1:1e4) all.equal(x, y))   # 0.93 seconds
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...