Betrachten Sie dies als eine "akademische" Frage. Ich habe darüber nachgedacht, von Zeit zu Zeit Nullen zu vermeiden, und dies ist ein Beispiel, bei dem ich keine zufriedenstellende Lösung finden kann.
Angenommen, ich speichere Messungen, bei denen gelegentlich bekannt ist, dass die Messung unmöglich ist (oder fehlt). Ich möchte diesen "leeren" Wert unter Vermeidung von NULL in einer Variablen speichern. In anderen Fällen ist der Wert möglicherweise unbekannt. Wenn also die Messungen für einen bestimmten Zeitraum vorliegen, kann eine Abfrage nach einer Messung innerhalb dieses Zeitraums drei Arten von Antworten zurückgeben:
- Die tatsächliche Messung zu diesem Zeitpunkt (z. B. ein beliebiger numerischer Wert einschließlich
0
) - Ein "fehlender" / "leerer" Wert (dh es wurde eine Messung durchgeführt, und der Wert ist zu diesem Zeitpunkt als leer bekannt ).
- Ein unbekannter Wert (dh zu diesem Zeitpunkt wurde noch keine Messung durchgeführt. Es kann leer sein, es kann sich aber auch um einen anderen Wert handeln).
Wichtige Klarstellung:
Angenommen, Sie hatten eine Funktion, get_measurement()
die "leer", "unbekannt" und einen Wert vom Typ "Ganzzahl" zurückgibt. Ein numerischer Wert impliziert, dass bestimmte Operationen für den Rückgabewert ausgeführt werden können (Multiplikation, Division, ...), aber die Verwendung solcher Operationen für NULL-Werte führt zum Absturz der Anwendung, wenn sie nicht abgefangen werden.
Ich möchte in der Lage sein, Code zu schreiben, zum Beispiel ohne NULL-Prüfungen (Pseudocode):
>>> value = get_measurement() # returns `2`
>>> print(value * 2)
4
>>> value = get_measurement() # returns `Empty()`
>>> print(value * 2)
Empty()
>>> value = get_measurement() # returns `Unknown()`
>>> print(value * 2)
Unknown()
Beachten Sie, dass keine der print
Anweisungen Ausnahmen verursachte (da keine NULL-Werte verwendet wurden). Die leeren und unbekannten Werte würden sich also nach Bedarf ausbreiten, und die Überprüfung, ob ein Wert tatsächlich "unbekannt" oder "leer" ist, könnte verzögert werden, bis er wirklich notwendig ist (wie das Speichern / Serialisieren des Wertes irgendwo).
Randbemerkung: Der Grund, warum ich NULL vermeiden möchte, ist in erster Linie ein Rätsel. Wenn ich etwas erledigen möchte, bin ich nicht gegen die Verwendung von NULL-Werten, aber ich habe festgestellt, dass das Vermeiden von NULL-Werten den Code in einigen Fällen viel robuster machen kann.
0
,[]
oder{}
(der Skalar 0, die leere Liste bzw. die leere Karte). Auch die „fehlender“ / „unbekannt“ Wert ist im Grunde genau das, wasnull
für - es bedeutet , dass es könnte dort ein Objekt sein, aber es ist nicht.Antworten:
Zumindest bei funktionalen Sprachen ist es üblich, eine diskriminierte Union zu verwenden. Dies ist dann ein Wert, der eines von einem gültigen int ist, ein Wert, der "fehlt" oder ein Wert, der "unbekannt" anzeigt. In F # könnte es ungefähr so aussehen:
Ein
Measurement
Wert ist dann aReading
, mit einem int-Wert oder aMissing
oderUnknown
mit den Rohdaten alsvalue
(falls erforderlich).Wenn Sie jedoch keine Sprache verwenden, die diskriminierte Gewerkschaften oder deren Äquivalente unterstützt, ist dieses Muster für Sie wahrscheinlich nicht von großem Nutzen. Dort können Sie beispielsweise eine Klasse mit einem Aufzählungsfeld verwenden, das angibt, welche der drei Klassen die richtigen Daten enthält.
quelle
std::variant
(und seine spirituellen Vorgänger).Wenn Sie nicht bereits wissen, was eine Monade ist, wäre heute ein großartiger Tag zum Lernen. Ich habe hier eine sanfte Einführung für OO-Programmierer:
https://ericlippert.com/2013/02/21/monads-part-one/
Ihr Szenario ist eine kleine Erweiterung der "vielleicht Monade", auch bekannt als
Nullable<T>
in C # undOptional<T>
in anderen Sprachen.Angenommen, Sie haben einen abstrakten Typ zur Darstellung der Monade:
und dann drei Unterklassen:
Wir brauchen eine Implementierung von Bind:
Daraus können Sie diese vereinfachte Version von Bind schreiben:
Und jetzt bist du fertig. Sie haben eine
Measurement<int>
in der Hand. Du willst es verdoppeln:Und folge der Logik; wenn
m
istEmpty<int>
dannasString
istEmpty<String>
, ausgezeichnet.Ebenso, wenn wir haben
und
dann können wir zwei messungen kombinieren:
und wieder, wenn
First()
istEmpty<int>
dannd
istEmpty<double>
und so weiter.Der Schlüsselschritt besteht darin, den Bindevorgang korrekt auszuführen . Überleg es dir gut.
quelle
Null
mitNullable
+ gewissen Standardcode? :)Measurement<T>
handelt es sich also um den monadischen Typ.Ich denke, dass in diesem Fall eine Variation eines Null-Objektmusters nützlich wäre:
Sie können daraus eine Struktur machen, Equals / GetHashCode / ToString überschreiben, implizite Konvertierungen von oder nach hinzufügen
int
und, wenn Sie ein NaN-ähnliches Verhalten wünschen, auch Ihre eigenen arithmetischen Operatoren implementieren, so dass z.Measurement.Unknown * 2 == Measurement.Unknown
.Das heißt, C #
Nullable<int>
implementiert all das, mit der einzigen Einschränkung, dass Sie nicht zwischen verschiedenen Arten vonnull
s unterscheiden können . Ich bin keine Java-Person, aber ich verstehe, dass JavaOptionalInt
ähnlich ist und andere Sprachen wahrscheinlich ihre eigenen Einrichtungen haben, um einenOptional
Typ darzustellen .quelle
Value
Getter, was unbedingt fehlschlagen sollte, da man einUnknown
Back nicht in ein konvertieren kannint
. Wenn die Messung beispielsweise eineSaveToDatabase()
Methode hätte, würde eine gute Implementierung wahrscheinlich keine Transaktion ausführen, wenn das aktuelle Objekt ein Nullobjekt ist (entweder durch Vergleich mit einem Singleton oder durch Überschreiben einer Methode).Wenn Sie buchstäblich eine ganze Zahl verwenden MÜSSEN, gibt es nur eine mögliche Lösung. Verwenden Sie einige der möglichen Werte als "magische Zahlen", die "fehlende" und "unbekannte" bedeuten.
zB 2,147,483,647 und 2,147,483,646
Wenn Sie das int nur für "echte" Messungen benötigen, erstellen Sie eine kompliziertere Datenstruktur
Wichtige Klarstellung:
Sie können die mathematischen Anforderungen erfüllen, indem Sie die Operatoren für die Klasse überladen
quelle
Option<Option<Int>>
type Measurement = Option<Int>
für ein Ergebnis, das eine Ganzzahl oder ein leerer Lesevorgang war, ist dies in Ordnung, ebensoOption<Measurement>
für eine Messung, die möglicherweise durchgeführt wurde oder nicht .Wenn Ihre Variablen Gleitkommazahlen sind, hat IEEE754 (der Gleitkommazahlenstandard, der von den meisten modernen Prozessoren und Sprachen unterstützt wird) Ihren Rücken: Es ist eine wenig bekannte Funktion, aber der Standard definiert nicht eine, sondern eine ganze Familie von NaN -Werte (Not-a-Number), die für beliebige anwendungsdefinierte Bedeutungen verwendet werden können. In Gleitkommazahlen mit einfacher Genauigkeit haben Sie beispielsweise 22 freie Bits, mit denen Sie zwischen 2 ^ {22} Typen ungültiger Werte unterscheiden können.
Normalerweise stellen Programmierschnittstellen nur eine von ihnen zur Verfügung (z. B. Numpy's
nan
). Ich weiß nicht, ob es eine integrierte Möglichkeit gibt, die anderen zu generieren, außer der expliziten Bit-Manipulation, aber es geht nur darum, ein paar Routinen auf niedriger Ebene zu schreiben. (Sie werden auch eine benötigen, um sie voneinander zu unterscheiden, da sie vom Design hera == b
immer false zurückgibt, wenn eine von ihnen eine NaN ist.)Ihre Verwendung ist besser, als Ihre eigene "magische Zahl" neu zu erfinden, um ungültige Daten zu signalisieren, da sie sich korrekt verbreiten und Ungültigkeit signalisieren: Sie riskieren beispielsweise nicht, sich in den Fuß zu schießen, wenn Sie eine
average()
Funktion verwenden und vergessen, nach ihnen zu suchen Ihre besonderen Werte.Das einzige Risiko besteht darin, dass Bibliotheken sie nicht korrekt unterstützen, da sie eine ziemlich unklare Funktion sind: Beispielsweise kann eine Serialisierungsbibliothek sie alle auf dasselbe reduzieren
nan
(was für die meisten Zwecke äquivalent aussieht).quelle
Im Anschluss an David Arno Antwort , können Sie so etwas wie eine diskriminierte Vereinigung in OOP, und in einer objekt funktionale Stil , wie sie tun , indem Scala lieferten, von Java 8 Funktionstypen oder einer Java - FP - Bibliothek wie Vavr oder Fugue es fühlt sich ziemlich natürlich etwas zu schreiben wie:
Drucken
( Vollständige Implementierung als Kern .)
Eine FP-Sprache oder Bibliothek bietet andere Tools wie
Try
(akaMaybe
) (ein Objekt, das entweder einen Wert oder einen Fehler enthält) undEither
(ein Objekt, das entweder einen Erfolgswert oder einen Fehlerwert enthält), die auch hier verwendet werden könnten.quelle
Die ideale Lösung für Ihr Problem hängt davon ab, warum Ihnen der Unterschied zwischen einem bekannten Fehler und einer bekannten unzuverlässigen Messung wichtig ist und welche nachgelagerten Prozesse Sie unterstützen möchten. Beachten Sie, dass "nachgelagerte Prozesse" in diesem Fall menschliche Bediener oder andere Entwickler nicht ausschließen.
Das bloße Aufstellen einer "zweiten Variante" von Null gibt den nachgeschalteten Prozessen nicht genügend Informationen, um eine vernünftige Reihe von Verhaltensweisen abzuleiten.
Wenn Sie sich stattdessen auf kontextbezogene Annahmen über die Ursache schlechten Verhaltens stützen, die durch nachgeschalteten Code verursacht werden, würde ich das schlechte Architektur nennen.
Wenn Sie genug wissen, um zwischen einem Grund für einen Fehler und einem Fehler ohne bekannten Grund zu unterscheiden, und diese Informationen künftige Verhaltensweisen beeinflussen, sollten Sie dieses Wissen nachgelagert kommunizieren oder inline verarbeiten.
Einige Muster für den Umgang damit:
null
quelle
Wenn es mir darum ging, "etwas zu erledigen", anstatt eine elegante Lösung zu finden, bestand der schnelle und schmutzige Hack darin, einfach die Zeichenfolgen "unbekannt", "fehlend" und "Zeichenfolgendarstellung meines numerischen Werts" zu verwenden, was dann der Fall wäre aus einer Zeichenfolge konvertiert und nach Bedarf verwendet. Schneller als das Schreiben implementiert und zumindest unter Umständen völlig ausreichend. (Ich bilde jetzt einen Wettpool für die Anzahl der Abstimmungen ...)
quelle
Der Kern der Frage lautet: "Wie gebe ich zwei unabhängige Informationen von einer Methode zurück, die ein einzelnes int zurückgibt? Ich möchte meine Rückgabewerte nie überprüfen, und Nullen sind schlecht. Verwenden Sie sie nicht."
Schauen wir uns an, was Sie weitergeben möchten. Sie übergeben entweder eine Ganzzahl oder eine Nicht-Ganzzahl- Begründung dafür, warum Sie die Ganzzahl nicht angeben können. Die Frage besagt, dass es nur zwei Gründe geben wird, aber jeder, der jemals eine Aufzählung gemacht hat, weiß, dass jede Liste wachsen wird. Es ist einfach sinnvoll, andere Gründe anzugeben.
Auf den ersten Blick scheint dies ein guter Fall für das Auslösen einer Ausnahme zu sein.
Wenn Sie dem Aufrufer etwas Besonderes mitteilen möchten, das nicht im Rückgabetyp enthalten ist, sind Ausnahmen häufig das geeignete System: Ausnahmen betreffen nicht nur Fehlerzustände und ermöglichen es Ihnen, eine Vielzahl von Kontexten und Begründungen zurückzugeben, um zu erklären, warum dies nur möglich ist heute nicht.
Und dies ist das EINZIGE System, mit dem Sie garantiert gültige Ints zurückgeben können und das garantiert, dass jeder int-Operator und jede Methode, die Ints akzeptiert, den Rückgabewert dieser Methode akzeptieren kann, ohne jemals nach ungültigen Werten wie null oder magischen Werten suchen zu müssen.
Aber Ausnahmen sind nur dann wirklich eine gültige Lösung, wenn dies, wie der Name schon sagt, ein Ausnahmefall ist und nicht der normale Geschäftsverlauf.
Und ein Try / Catch-and-Handler ist genau so wichtig wie ein Null-Check, gegen den überhaupt Einspruch erhoben wurde.
Und wenn der Anrufer das try / catch nicht enthält, muss der Anrufer das tun und so weiter.
Ein naiver zweiter Durchgang lautet: "Es ist eine Messung. Negative Entfernungsmessungen sind unwahrscheinlich." Für einige Messungen von Y können Sie also nur consts für haben
Dies ist die Art und Weise, wie dies in vielen alten C-Systemen und sogar in modernen Systemen, in denen es eine echte Einschränkung für int gibt und Sie es nicht in eine Struktur oder eine Monade irgendeines Typs umbrechen können, getan wird.
Wenn die Messungen negativ sein können, vergrößern Sie einfach Ihren Datentyp (z. B. long int) und lassen die magischen Werte höher als den Bereich des int sein. Beginnen Sie im Idealfall mit einem Wert, der in einem Debugger deutlich angezeigt wird.
Es gibt gute Gründe, sie als separate Variable zu haben, anstatt nur magische Zahlen zu haben. Zum Beispiel strikte Typisierung, Wartbarkeit und Erfüllung der Erwartungen.
In unserem dritten Versuch betrachten wir Fälle, in denen es der normale Geschäftsverlauf ist, nicht int-Werte zu haben. Zum Beispiel, wenn eine Auflistung dieser Werte mehrere nicht ganzzahlige Einträge enthalten kann. Dies bedeutet, dass ein Ausnahmebehandler möglicherweise der falsche Ansatz ist.
In diesem Fall ist es ein guter Fall für eine Struktur, die das int und die Begründung übergibt. Wiederum kann diese Begründung nur eine Konstante wie die obige sein, aber anstatt beide im selben int zu halten, speichern Sie sie als verschiedene Teile einer Struktur. Anfangs haben wir die Regel, dass, wenn das Grundprinzip festgelegt ist, das int nicht festgelegt wird. An diese Regel sind wir aber nicht mehr gebunden; Bei Bedarf können wir auch Begründungen für gültige Zahlen liefern.
So oder so, jedes Mal, wenn Sie es aufrufen, benötigen Sie Boilerplate, um das Grundprinzip zu testen, um festzustellen, ob das int gültig ist. Ziehen Sie dann den int-Teil heraus und verwenden Sie ihn, wenn das Grundprinzip dies zulässt.
Hier müssen Sie Ihre Argumentation hinter "Don't Use Null" untersuchen.
Wie Ausnahmen soll Null einen Ausnahmezustand bedeuten.
Wenn ein Aufrufer diese Methode aufruft und den "rationalen" Teil der Struktur vollständig ignoriert, eine Zahl ohne Fehlerbehandlung erwartet und eine Null erhält, behandelt er die Null als Zahl und ist falsch. Wenn es eine magische Zahl erhält, behandelt es das als eine Zahl und ist falsch. Aber wenn es eine Null wird, wird es umfallen , wie es verdammt gut tun sollte.
Jedes Mal, wenn Sie diese Methode aufrufen, müssen Sie den Rückgabewert überprüfen. Sie behandeln jedoch die ungültigen Werte, ob bandintern oder bandextern, try / catch, überprüfen die Struktur auf eine "rationale" Komponente und überprüfen das int nach einer magischen Zahl suchen oder ein Int auf eine Null prüfen ...
Die Alternative, die Multiplikation einer Ausgabe zu behandeln, die ein ungültiges int und eine Begründung wie "Mein Hund hat diese Messung gefressen" enthalten könnte, besteht darin, den Multiplikationsoperator für diese Struktur zu überladen.
... und überladen Sie dann jeden anderen Operator in Ihrer Anwendung, der möglicherweise auf diese Daten angewendet wird.
... und dann alle Methoden überladen, die Ints benötigen könnten.
... Und all diese Überladungen müssen weiterhin Prüfungen auf ungültige Ints enthalten, damit Sie den Rückgabetyp dieser einen Methode so behandeln können, als wäre er zum Zeitpunkt des Aufrufs immer ein gültiger Int.
Die ursprüngliche Prämisse ist also in verschiedener Hinsicht falsch:
quelle
Ich verstehe die Prämisse Ihrer Frage nicht, aber hier ist die Nennwertantwort. Für Vermisst oder Leer könnten Sie tun
math.nan
(keine Zahl). Sie können alle mathematischen Operationen ausführen,math.nan
und es wird bleibenmath.nan
.Sie können
None
(Python's null) für einen unbekannten Wert verwenden. Sie sollten sowieso keinen unbekannten Wert manipulieren, und einige Sprachen (Python ist keine von ihnen) haben spezielle Nulloperatoren, sodass die Operation nur ausgeführt wird, wenn der Wert nicht null ist, andernfalls bleibt der Wert null.Andere Sprachen haben Schutzklauseln (wie Swift oder Ruby) und Ruby hat eine bedingte vorzeitige Rückkehr.
Ich habe dies in Python auf verschiedene Arten gelöst gesehen:
__mult__
sodass keine Ausnahmen ausgelöst werden, wenn Ihre Werte für Unbekannt oder Fehlend angezeigt werden. Numpy und Pandas könnten solche Fähigkeiten haben.Unknown
oder -1 / -2) und einer if-Anweisungquelle
Wie der Wert im Speicher abgelegt wird, hängt von der Sprache und den Implementierungsdetails ab. Ich denke, Sie meinen damit, wie sich das Objekt für den Programmierer verhalten soll. (So lese ich die Frage, sag mir, ob ich falsch liege.)
Sie haben bereits in Ihrer Frage eine Antwort darauf vorgeschlagen: Verwenden Sie Ihre eigene Klasse, die jede mathematische Operation akzeptiert und sich selbst zurückgibt, ohne eine Ausnahme auszulösen. Sie sagen, Sie möchten dies, weil Sie Nullprüfungen vermeiden möchten.
Lösung 1: Vermeiden Sie keine Nullprüfungen
Missing
kann dargestellt werden alsmath.nan
Unknown
kann dargestellt werden alsNone
Wenn Sie mehr als einen Wert haben, können Sie
filter()
die Operation nur auf Werte anwenden, die nichtUnknown
oder sindMissing
, oder auf Werte, die Sie für die Funktion ignorieren möchten.Ich kann mir kein Szenario vorstellen, in dem Sie eine Nullprüfung für eine Funktion benötigen, die auf einen einzelnen Skalar wirkt. In diesem Fall empfiehlt es sich, Nullprüfungen zu erzwingen.
Lösung 2: Verwenden Sie einen Dekorateur, der Ausnahmen erkennt
In diesem Fall
Missing
könnte ausgelöst werdenMissingException
undUnknown
könnte ausgelöst werden,UnknownException
wenn Operationen daran ausgeführt werden.Der Vorteil dieses Ansatzes besteht darin, dass die Eigenschaften von
Missing
undUnknown
nur dann unterdrückt werden, wenn Sie ausdrücklich verlangen, dass sie unterdrückt werden. Ein weiterer Vorteil ist, dass dieser Ansatz sich selbst dokumentiert: Jede Funktion zeigt an, ob sie ein Unbekanntes oder ein Fehlendes erwartet und wie die Funktion.Wenn Sie bei einem Funktionsaufruf nicht erwarten, dass eine fehlende Nachricht eine fehlende Nachricht enthält, wird die Funktion sofort ausgelöst und zeigt Ihnen genau, wo der Fehler aufgetreten ist, anstatt stillschweigend eine fehlende Nachricht in der Aufrufkette weiterzugeben. Gleiches gilt für Unknown.
sigmoid
kann immer noch anrufensin
, auch wenn es keinMissing
oder erwartetUnknown
, dasigmoid
der dekorateur die ausnahme abfängt.quelle
Beides klingt nach Fehlerzuständen, daher würde ich beurteilen, dass die beste Option hier darin besteht
get_measurement()
, beide sofort als Ausnahmen zu werfen (wie z. B.DataSourceUnavailableException
oderSpectacularFailureToGetDataException
). Wenn eines dieser Probleme auftritt, kann der Datenerfassungscode sofort darauf reagieren (z. B. indem er es im letzteren Fall erneut versucht) und mussget_measurement()
nur einen zurückgeben,int
wenn die Daten erfolgreich aus den Daten abgerufen werden können Quelle - und Sie wissen, dass dasint
gültig ist.Wenn Ihre Situation keine Ausnahmen unterstützt oder diese nicht in großem Umfang nutzt, ist die Verwendung von Fehlercodes eine gute Alternative, die möglicherweise über eine separate Ausgabe an zurückgegeben werden
get_measurement()
. Dies ist das idiomatische Muster in C, in dem die tatsächliche Ausgabe in einem Eingabezeiger gespeichert und ein Fehlercode als Rückgabewert zurückgegeben wird.quelle
Die gegebenen Antworten sind in Ordnung, spiegeln aber immer noch nicht die hierarchische Beziehung zwischen Wert, leer und unbekannt wider.
Hässlich (wegen der fehlgeschlagenen Abstraktion), aber voll funktionsfähig wäre (in Java):
Hier sind funktionale Sprachen mit einem schönen Typensystem besser.
Tatsächlich: Die leeren / fehlenden und unbekannten * Nicht-Werte scheinen eher Teil eines Prozesszustands, einer Produktionspipeline zu sein. Wie Excel-Tabellenkalkulationszellen mit Formeln, die auf andere Zellen verweisen. Dort würde man vielleicht an das Speichern von kontextbezogenen Lambdas denken. Das Ändern einer Zelle würde alle rekursiv abhängigen Zellen neu bewerten.
In diesem Fall würde ein int-Wert von einem int-Lieferanten erhalten. Ein leerer Wert würde bewirken, dass ein int-Lieferant eine leere Ausnahme auslöst oder leer wird (rekursiv nach oben). Ihre Hauptformel würde alle Werte verbinden und möglicherweise auch ein Leerzeichen (Wert / Ausnahme) zurückgeben. Ein unbekannter Wert würde die Auswertung durch Auslösen einer Ausnahme deaktivieren.
Werte wären wahrscheinlich beobachtbar, wie eine Java-gebundene Eigenschaft, die die Listener über Änderungen benachrichtigt.
Kurz gesagt: Das wiederkehrende Muster, dass Werte mit zusätzlichen leeren und unbekannten Zuständen benötigt werden, scheint darauf hinzudeuten, dass ein Datenmodell mit mehr Tabellenkalkulation wie gebundenen Eigenschaften möglicherweise besser ist.
quelle
Ja, das Konzept mehrerer verschiedener NA-Typen existiert in einigen Sprachen. Dies gilt umso mehr für statistische Fälle, in denen dies aussagekräftiger ist (d. h. die enorme Unterscheidung zwischen " Missing-At-Random", "Missing-Completely-At-Random" und "Missing-Not-At-Random" ).
Wenn wir nur Widgetlängen messen, ist es nicht entscheidend, zwischen "Sensorausfall" oder "Stromausfall" oder "Netzwerkausfall" zu unterscheiden (obwohl "numerischer Überlauf" Informationen übermittelt).
B. beim Data Mining oder bei einer Umfrage, bei der die Befragten nach ihrem Einkommen oder dem HIV-Status gefragt werden, unterscheidet sich das Ergebnis von "Unbekannt" von "Antwort ablehnen", und Sie können sehen, dass unsere vorherigen Annahmen darüber, wie letzteres unterstellt werden soll, eher zutreffen anders sein als die ersteren. Sprachen wie SAS unterstützen also mehrere verschiedene NA-Typen. die R-Sprache nicht, aber die Benutzer müssen sich sehr oft darum kümmern; NAs an verschiedenen Punkten in einer Pipeline können verwendet werden, um sehr unterschiedliche Dinge zu bezeichnen.
In Bezug auf die Darstellung verschiedener NA-Typen in Mehrzwecksprachen, die diese nicht unterstützen, hacken die Leute im Allgemeinen Dinge wie Gleitkomma-NaN (erfordert die Konvertierung von Ganzzahlen), Enums oder Sentinels (z. B. 999 oder -1000) für Ganzzahlen oder kategoriale Werte. Normalerweise gibt es keine sehr klare Antwort, sorry.
quelle
R verfügt über eine integrierte Unterstützung für fehlende Werte. https://medium.com/coinmonks/dealing-with-missing-data-using-r-3ae428da2d17
Edit: weil ich downvoted wurde, werde ich ein bisschen erklären.
Wenn Sie sich mit Statistik befassen, empfehle ich die Verwendung einer Statistiksprache wie R, da R von Statistikern für Statistiker geschrieben wird. Fehlende Werte sind ein so großes Thema, dass sie Ihnen ein ganzes Semester lang beibringen. Und es gibt große Bücher nur über fehlende Werte.
Sie können jedoch fehlende Daten markieren, z. B. Punkte oder "fehlende" oder was auch immer. In R können Sie definieren, was Sie mit Vermissen meinen. Sie müssen sie nicht konvertieren.
Der normale Weg, einen fehlenden Wert zu definieren, besteht darin, ihn als zu markieren
NA
.Dann können Sie sehen, welche Werte fehlen.
Und dann wird das Ergebnis sein;
Wie Sie sehen können,
""
fehlt es nicht. Sie können""
als unbekannt bedrohen . UndNA
fehlt.quelle
Gibt es einen Grund, warum die Funktionalität des
*
Bedieners nicht geändert werden kann?Bei den meisten Antworten handelt es sich um eine Art Nachschlagewert. In diesem Fall ist es jedoch möglicherweise einfacher, den mathematischen Operator zu ändern.
Sie würden dann ähnlich zu haben , in der Lage
empty()
/unknown()
Funktionalität in Ihrem gesamten Projekt.quelle