Ich war überrascht zu erfahren, dass R keine praktische Funktion hat, um zu überprüfen, ob die Zahl eine Ganzzahl ist.
is.integer(66) # FALSE
Die Hilfedateien warnen :
is.integer(x)
testet nicht, ob esx
ganzzahlige Zahlen enthält! Verwenden Sie dazuround
wie in der Funktionis.wholenumber(x)
in den Beispielen.
Das Beispiel hat diese benutzerdefinierte Funktion als "Problemumgehung"
is.wholenumber <- function(x, tol = .Machine$double.eps^0.5) abs(x - round(x)) < tol
is.wholenumber(1) # is TRUE
Wenn ich eine Funktion schreiben müsste, um nach Ganzzahlen zu suchen, würde ich, vorausgesetzt ich hätte die obigen Kommentare nicht gelesen, eine Funktion schreiben, die etwas in der Art von geht
check.integer <- function(x) {
x == round(x)
}
Wo würde mein Ansatz scheitern? Was wäre deine Arbeit, wenn du in meinen hypothetischen Schuhen steckst?
round(x)
es richtig implementiert wird, das Ergebnis der Anwendung auf eine Ganzzahl immer diese Ganzzahl wäre ...is.integer
prüft das Rechenkonzept, diecheck.integer
Benutzerfunktion prüft den mathematischen Gesichtspunkt.Antworten:
Eine andere Alternative besteht darin, den Bruchteil zu überprüfen:
oder, wenn Sie innerhalb einer bestimmten Toleranz prüfen möchten:
quelle
x <- 5-1e-8; x%%1
ergibt 0,9999999 (wastol==1e-5
zum Beispiel bedeuten würde ), dasx
ist keine ganze Zahl.min(abs(c(x%%1, x%%1-1))) < tol
stattabs(min(x%%1, x%%1-1)) < tol
anders sein, Sie werdenFALSE
für jede ganze Zahl ...as.integer(x) == x
? Es wird 3 oder 3.0 nicht ablehnen, wie esis.integer(x)
würde, und es wird 3.1 fangen.Hier ist eine Lösung mit einfacheren Funktionen und ohne Hacks:
Außerdem können Sie auf Wunsch einen ganzen Vektor auf einmal testen. Hier ist eine Funktion:
Sie können es ändern, um es
*apply
im Fall von Vektoren, Matrizen usw. zu verwenden.quelle
if
else
könnte einfach gemacht werdenisTRUE(test)
. Das ist in der Tat alles, was Sie brauchen, um dieif
else
Klausel und diereturn
Anweisungen zu ersetzen, da R automatisch das Ergebnis der letzten Bewertung zurückgibt.testInteger(1.0000001)
[1] FALSEtestInteger(1.00000001)
[1] TRUEall(a == as.integer(a))
umgeht dieses Problem! 'Das Lesen der R-Sprachdokumentation
as.integer
hat mehr damit zu tun, wie die Nummer gespeichert wird, als wenn sie praktisch einer Ganzzahl entspricht.is.integer
testet, ob die Zahl als Ganzzahl deklariert ist. Sie können eine Ganzzahl deklarieren, indem Sie ein Nachher setzenL
.Auch Funktionen wie
round
geben eine deklarierte Ganzzahl zurück, mit der Sie arbeitenx==round(x)
. Das Problem bei diesem Ansatz ist, was Sie praktisch als Ganzzahl betrachten. Das Beispiel verwendet weniger Präzision zum Testen der Äquivalenz.Abhängig von Ihrer Anwendung können Sie auf diese Weise in Schwierigkeiten geraten.
quelle
Hier ist ein scheinbar zuverlässiger Weg:
Diese Lösung ermöglicht auch Ganzzahlen in wissenschaftlicher Notation:
quelle
check.integer(1e4)
ist WAHR, währendcheck.integer(1e5)
es FALSCH ist.is.wholenumber
oder eine der anderen Lösungen, die in anderen Antworten angegeben sind. Diese sollten nicht anders sein :check.integer(1e22); check.integer(1e23)
. Sie können natürlich den regulären Ausdruck ändern, um dies zu beheben, aber dieser Ansatz ist schrecklich. (Kommentar stammt von der Zuschreibung im Installationspaket.)format(40, scientific = FALSE, digits = 20)
stattdessen. Ich habe die Antwort aktualisiert. Danke, dass du es entdeckt hast.1.0000000000000001 == 1L [1] TRUE
. Aber meine Lösung ist besser, wenn Sie bereits eine Zahl in Zeichenfolgenform erhaltencheck.integer("1000000000000000000000000000000000001") [1] TRUE
Es scheint, dass Sie keine Notwendigkeit sehen, eine gewisse Fehlertoleranz zu berücksichtigen. Es wäre nicht erforderlich, wenn alle Ganzzahlen als Ganzzahlen eingegeben würden. Manchmal sind sie jedoch das Ergebnis von arithmetischen Operationen, die an Genauigkeit verlieren. Beispielsweise:
Beachten Sie, dass dies nicht die Schwäche von R ist. Alle Computersoftware haben einige Genauigkeitsgrenzen.
quelle
Von
Hmisc::spss.get
:viel sicherere Option, IMHO, da es das Problem der Maschinengenauigkeit "umgeht". Wenn Sie es versuchen
is.integer(floor(1))
, werden Sie bekommenFALSE
. Übrigens wird Ihre Ganzzahl nicht als Ganzzahl gespeichert, wenn sie größer als der.Machine$integer.max
Wert ist, dh standardmäßig 2147483647, also ändern Sie entweder deninteger.max
Wert oder führen Sie die alternativen Überprüfungen durch ...quelle
x <- sqrt(2)^2
, dannall(floor(x) == x, na.rm = TRUE)
kehren Sie zurückFALSE
Sie können einfache wenn Bedingung wie verwenden:
quelle
In R kann durch die Klassenfunktion bestimmt werden, ob eine Zahl numerisch oder ganzzahlig ist. Im Allgemeinen werden alle Zahlen als numerisch gespeichert. Um eine Zahl explizit als Ganzzahl zu definieren, müssen Sie nach der Zahl 'L' angeben.
Beispiel:
[1] "numerisch"
[1] "Ganzzahl"
Ich hoffe, das war es, was gebraucht wurde. Vielen Dank :)
quelle
[UPDATE] =============================================== ===============
In Bezug auf die [ALTE] Antwort hier unten habe ich festgestellt, dass es funktioniert hat, weil ich alle Zahlen in einen einzelnen Atomvektor gesetzt habe. Einer von ihnen war ein Charakter, also wurde jeder zu einem Charakter.
Wenn wir eine Liste verwenden (daher kommt es nicht zu Zwang), bestehen alle Tests korrekt, bis auf einen :
1/(1 - 0.98)
, der a bleibtnumeric
. Dies liegt daran, dass dertol
Parameter standardmäßig verwendet wird100 * .Machine$double.eps
und diese Zahl bei weitem nicht50
kleiner als das Doppelte ist. Im Grunde genommen haben wir für diese Art von Zahlen auf unsere Toleranz entscheiden!Also, wenn Sie wollen, dass alle Tests wurden
TRUE
, können Sieassertive::is_whole_number(x, tol = 200 * .Machine$double.eps)
Wie auch immer, ich bestätige, dass IMO durchsetzungsfähig die beste Lösung bleibt.
Hier unten ein Reprex für dieses [UPDATE].
Erstellt am 23.07.2019 vom reprex-Paket (v0.3.0)
[ALT] =============================================== ==================
IMO die beste Lösung kommt aus dem
assertive
Paket (das im Moment alle positiven und negativen Beispiele in diesem Thread löst):Erstellt am 23.07.2019 vom reprex-Paket (v0.3.0)
quelle
Wenn Sie keine eigene Funktion schreiben möchten, versuchen Sie es mit
check.integer
dem Paket installr . Derzeit wird die Antwort von VitoshKa verwendet .Versuchen Sie es auch mit
check.numeric(v, only.integer=TRUE)
dem Paket varhandle , das den Vorteil hat, vektorisiert zu werden.quelle
Einmal kann auch verwendet werden
dplyr::near
:Es gilt für jeden Vektor
a
und verfügt über einen optionalen Toleranzparameter.quelle
Ich bin mir nicht sicher, was Sie erreichen wollen. Aber hier sind einige Gedanken:
1. In Ganzzahl konvertieren:
num = as.integer(123.2342)
2. Überprüfen Sie, ob eine Variable eine Ganzzahl ist:
is.integer(num)
typeof(num)=="integer"
quelle