A previous post skłonił mnie do opublikowania tego pytania. Wydaje się, że najlepszą praktyką jest ponowne przypisanie ==
do isTRUE(all.equal())
(i !=
do !isTRUE(all.equal())
. Zastanawiam się, czy inni robią to w praktyce? Właśnie sobie sprawę, że używam ==
i !=
do równości numerycznej całej mojej bazy kodowej. Moja pierwsza reakcja było to, że muszę wykonać peeling i przekonwertować do all.equal
.Ale faktycznie za każdym razem używać ==
i !=
Chcę przetestować równości (bez względu na typ danych) .W rzeczywistości nie jestem pewien, co te operacje będą testować dla innych niż równości Jestem pewien, że brakuje mi tutaj pewnej koncepcji: czy ktoś może mnie oświecić? Jedynym argumentem, jaki widzę przeciwko temu podejściu jest to, że w niektórych przypadkach dwie nieidentyczne liczby wydają się identyczne z powodu tolerancji all.equal
. Ale powiedziano nam, że dwie liczby, które w rzeczywistości są identyczne, mogą nie przejść identical()
ze względu na sposób ich przechowywania w pamięci. Więc o co właściwie chodzi, aby nie spłacać all.equal
?Czy ponownie przypisujesz == i! = Do isTRUE (all.equal())?
Odpowiedz
W nawiązywaniu do @joran napotkasz problemy z liczbami zmiennoprzecinkowymi z ==
i !=
w prawie każdym innym języku. Jednym ważnym aspektem ich w R jest część wektoryzacji.
Znacznie lepiej zdefiniować nową funkcję almostEqual
, fuzzyEqual
lub podobną. Niefortunne jest, że nie ma takiej podstawowej funkcji. all.equal
nie jest bardzo wydajny, ponieważ obsługuje wszystkie rodzaje obiektów i zwraca string opisujący różnicę, gdy w większości przypadków po prostu chcesz TRUE
lub FALSE
.
Oto przykład takiej funkcji. Jest wektoryzowany jak ==
.
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
... to jest około 2x szybciej niż all.equal
dla wartości skalarnych, a znacznie szybciej wektorami.
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
Tommy - po kilku testach myślę, że jest błąd w tej funkcji. Rozważmy: matrixa = round (matrix (rnorm (9), nrow = 3, ncol = 3), 6) matrixb = matrixa - .001 almostEqual (matrixa, matrixb, tolerancja = .001) – SFun28
Nawet w ten sposób powstaje FALSE czasami: almostEqual (matrixa, matrixb, tolerancja = .01) – SFun28
@ SFun28 - Myślę, że kod jest poprawny. Zamiast tego wypróbuj 'all.equal', a otrzymasz również PRAWDA. To dlatego, że jest WSPÓŁCZESNA tolerancja.'rnorm' może dawać duże (3.5) lub małe (0.0003) liczby, ale twój błąd dodawany do matrixb jest zawsze' 0.001'. Zamiast tego wypróbuj 'matrixb <- matrixa * 1.001'. – Tommy
- 1. R: all.equal() dla wielu obiektów?
- 2. Jak przypisujesz tablicę PHP do tablicy jQuery?
- 3. Błąd: isTRUE (gpclibPermitStatus()) nie jest PRAWDZIWY
- 4. Co się stanie, jeśli przypisujesz wartość do $ _REQUEST?
- 5. W jaki sposób przypisujesz statyczny atrybut danych do widoku embera?
- 6. REST i GET ... ponownie
- 7. Czy socket.io ponownie łączy się ponownie uruchomić connect?
- 8. Kiedy ponownie uruchomić i nie ponownie załadować Nginx?
- 9. backbone.js: Zaktualizuj model, ponownie sortuj i ponownie renderuj kolekcje modeli
- 10. GoogleApiClient onConnectionPo zawieszeniu, czy powinienem ponownie zadzwonić do mGoogleApiClient.connect()?
- 11. Czy można bezpiecznie przechowywać wystąpienie wyjątku i ponownie go użyć?
- 12. ponownie dołączyć źródła do intellij?
- 13. Wyczyść couchdb i uruchom ponownie
- 14. W jaki sposób prawidłowo przypisujesz projekty Open Source?
- 15. W jaki sposób dynamicznie przypisujesz atrybut "onclick" JavaScript?
- 16. Czy można ponownie wygenerować symbole dla exe?
- 17. Ponownie załaduj dane do UIPickerView
- 18. Jak sprawdzić, czy komputer został ponownie uruchomiony?
- 19. Mercurial - podstawowy proces, aby powrócić do scalenia i spróbuj ponownie
- 20. Czy możesz ponownie użyć przeniesionego std :: string?
- 21. Czy mogę ponownie wydrukować plik spool?
- 22. Czy wykres można odłączyć od obiektu ObjectContext i ponownie dołączyć do innego?
- 23. Pobierz, włamuj się i ponownie załaduj plik APK do Google Play. Czy to możliwe?
- 24. Jak przypisujesz konkretny NAME do tagu podczas korzystania ze stron wzorcowych?
- 25. ponownie o log4net i Unity IOC config
- 26. Czy executor ma być ponownie użyty?
- 27. Kontrola urządzeń Chrome ponownie otwierane/ponownie ładowane
- 28. W Stata jak przypisujesz długą listę nazw zmiennych do lokalnego makra?
- 29. Czy wektor :: shrink_to_fit może być ponownie przydzielony?
- 30. Czy funkcja main() została ponownie zgłoszona?
To wydawało się być dziwną rzeczą, po czym przeczytałem notatkę na stronie pomocy Porównanie: "Nie używaj == i! = Do testów, takich jak w wyrażeniach, gdzie musisz uzyskać pojedyncze PRAWDA lub FAŁSZ Jeśli nie masz absolutnej pewności, że nie może się zdarzyć nic niezwykłego, powinieneś użyć identycznej funkcji. " Więc może to nie jest taki absurdalny pomysł. –
Powiem "nie", nie powinieneś. Zamiast tego użyj 'identyczne' i trzymaj' == 'wokół wektoryzowanych porównań podczas podsekcji. – joran
Jeśli zaczniesz przeciążać typowe operatory, Twój kod będzie poważnie nieprzenośny. O wiele lepiej jest dowiedzieć się, co robi każdy operator lub funkcja i użyć odpowiedniego narzędzia do właściwej pracy. –