2016-06-29 5 views
10

Ich interessiere mich numerischen Skalar Identifizierung wie:Wie überprüfen Sie für einen Skalar in R?

doub <- 3.14 
intg <- 8L 

Ich weiß, dass diese als Länge einer Vektoren behandelt werden. So kann jede R Objekt x ist is.vector(x) && length(x) == 1 der richtige Weg, um zu überprüfen, ob x ein Skalar ist? length(x) == 1 für sich allein nicht ausreichend ist, da es eine true zurück, wenn es falsch ist, für einen Datenrahmen mit einer Spalte oder eine Liste mit einem Element zurückgeben sollte.

Gibt es einen Grund, warum es keine solche Funktion gibt is.scalar in Basis R implementiert? Aus irgendeinem Grund bereits erwähnt die beiden, die ich in anderen Funktionen nicht für den Datenrahmen Fall finden konnten, sind diese:

assertthat::is.scalar(data.frame(a = 1:2)) 
lambda.tools::is.scalar(data.frame(a = 1:2)) 

Warum sind die Ergebnisse dieser beiden Funktionsaufrufe unterschiedliche meinem Verständnis (und Definition), wie ein is.scalar Funktion sollte funktionieren?

+2

Sie wahrscheinlich 'wollen statt' is.vector' is.atomic'. –

+2

Was ist der Unterschied zwischen den beiden? – Alex

+0

Siehe "? Isatomic": "Es ist üblich, atomare Typen als atomare Vektoren zu bezeichnen, aber beachte, dass" is.vector' legt weitere Einschränkungen fest: ein Objekt kann atomar sein, aber kein Vektor (in diesem Sinne). " – MichaelChirico

Antwort

8

Ich denke, is.atomic zu Ihren Ansprüchen passt.

Denn warum is.vector ist wahrscheinlich nicht kompatibel, siehe zB:

is.atomic(list(1)) 
# [1] FALSE 

is.vector(list(1)) 
# [1] TRUE 

auf Ihre Objekte:

is.scalar <- function(x) is.atomic(x) && length(x) == 1L 

is.scalar(doub) 
# [1] TRUE 

is.scalar(intg) 
# [1] TRUE 

is.scalar(c(doub, intg)) 
# [1] FALSE 
8

Aufbauend auf dem answer von @MichaelChirico, es gibt ein paar andere Dinge, die is.scalar() sollte nachsehen.

Zunächst werden komplexe Zahlen der Regel nicht als Skalar betrachtet (obwohl ich diese Nutzung denke zwischen den Disziplinen können variieren).

comp <- 2+3i 
is.scalar <- function(x) is.atomic(x) && length(x) == 1L 
is.scalar(comp) 
# TRUE 

so sollten wir auch nach komplexen Zahlen suchen. Die einfache, aber naiv, Art und Weise, dies zu tun ist is.complex

is.scalar <- function(x) is.atomic(x) && length(x) == 1L && !is.complex(x) 
is.scalar(comp) 
# FALSE 

Leider zu verwenden, ist dies nicht ganz richtig ist, weil is.complex prüft nur, ob die Klasse ist "complex". Aber reelle Zahlen können Klasse = komplex haben, wenn ihre imaginäre Komponente Null ist.

is.complex(2+0i) 
# [1] TRUE 

So für reelle Zahlen testen wir, dass die imaginäre Komponente sind besser dran zu überprüfen Null Im(x)==0 Verwendung ist. Also, das führt uns zu einem Test für Skalare, die diese aussehen

is.scalar <- function(x) is.atomic(x) && length(x) == 1L && Im(x)==0 

Mehr trivialen, sollten Zeichen auch

is.scalar("x") 
# TRUE 
is.scalar <- function(x) is.atomic(x) && length(x) == 1L && !is.character(x) && Im(x)==0 
is.scalar("x") 
# FALSE 

Hinweis beseitigt werden, die wir testen für is.character(x) vor Im(x)==0 so dass faule Auswertung gewährleistet, dass Die Funktion versucht niemals, die imaginäre Komponente eines Zeichens zu finden, die einen Fehler auslösen würde.

+0

Warum also nicht einfach 'is.scalar Wastl

+1

@Wastl Es hängt von Ihrem Zweck und genau, was Sie testen möchten, aber mit Ihrer Definition 'is.scalar (x)' würde für z. "x = 1 + 0i", "x = NA" und "x = 1; attr (x, 'foo') = 1 ' – dww

Verwandte Themen