Typ aller Variablen abrufen


118

In R möchte ich am Ende meines Skripts eine Liste globaler Variablen abrufen und diese durchlaufen. Hier ist mein Code

#declare a few sample variables
a<-10
b<-"Hello world"
c<-data.frame()

#get all global variables in script and iterate over them
myGlobals<-objects()
for(i in myGlobals){
  print(typeof(i))     #prints 'character'
}

Mein Problem ist, dass typeof(i)immer zurückgegeben wird character, obwohl variabel aund ckeine Zeichenvariablen sind. Wie kann ich den ursprünglichen Variablentyp in der for-Schleife abrufen?


Hinweis für Personen, die diese Frage lesen: typeof()Gibt eine sehr allgemeine Information darüber, wie das Objekt im Speicher gespeichert ist. Für die meisten Anwendungsfälle, wenn Sie gute Informationen über eine Variable wissen möchten x, finden Sie weitere nützliche Informationen aus erhalten class(x), is(x)oder str(x)(in der Reihenfolge, wie viel Detail sie bieten). In Erics Antwort unten finden Sie Beispiele dafür, was typeof()Ihnen sagt: Faktoren sind integer; Listen, Datenrahmen, Modellobjekte, andere erweiterte Objekte sind nur list...
Gregor Thomas

Antworten:


109

Sie müssen verwenden get, um den Wert und nicht den Zeichennamen des Objekts zu erhalten, wie von ls:

x <- 1L
typeof(ls())
[1] "character"
typeof(get(ls()))
[1] "integer"

Alternativ können Sie für das dargestellte Problem Folgendes verwenden eapply:

eapply(.GlobalEnv,typeof)
$x
[1] "integer"

$a
[1] "double"

$b
[1] "character"

$c
[1] "list"

Lass dich perfekt arbeiten. Wissen Sie, ob es Leistungseinbußen gibt, wenn get () verwendet wird, um den Typ mehrerer großer Datenrahmen zu ermitteln, die in der von object () zurückgegebenen Variablenliste vorhanden sein können?

1
gethat seine Kritiker und ich würde mir vorstellen, eapplywäre schneller als eine interpretierte Schleife. Aber es gibt nur einen Weg, es herauszufinden ...
James

17

So erhalten Sie den Variablentyp, wenn er unter einem globalen Objekt versteckt ist:

Alles, was Sie benötigen, finden Sie im R-Handbuch zu Basistypen: https://cran.r-project.org/doc/manuals/R-lang.html#Basic-types

Sie object()müssen eingedrungen sein, get(...)bevor Sie hineinsehen können. Beispiel:

a <- 10
myGlobals <- objects()
for(i in myGlobals){
  typeof(i)         #prints character
  typeof(get(i))    #prints integer
}

So erhalten Sie den Variablentyp, den Sie in R haben

Die R- Funktiontypeof hat eine Vorspannung, um Ihnen beispielsweise den Typ in maximaler Tiefe zu geben.

library(tibble)

#expression              notes                                  type
#----------------------- -------------------------------------- ----------
typeof(TRUE)             #a single boolean:                     logical
typeof(1L)               #a single numeric with L postfixed:    integer
typeof("foobar")         #A single string in double quotes:     character
typeof(1)                #a single numeric:                     double
typeof(list(5,6,7))      #a list of numeric:                    list
typeof(2i)               #an imaginary number                   complex

#So far so good, but those who wish to keep their sanity go no further
typeof(5 + 5L)           #double + integer is coerced:          double
typeof(c())              #an empty vector has no type:          NULL
typeof(!5)               #a bang before a double:               logical
typeof(Inf)              #infinity has a type:                  double
typeof(c(5,6,7))         #a vector containing only doubles:     double
typeof(c(c(TRUE)))       #a vector of vector of logicals:       logical
typeof(matrix(1:10))     #a matrix of doubles has a type:       list

#Strangeness ahead, there be dragons: step carefully:
typeof(substr("abc",2,2))#a string at index 2 which is 'b' is:  character
typeof(c(5L,6L,7L))      #a vector containing only integers:    integer
typeof(c(NA,NA,NA))      #a vector containing only NA:          logical
typeof(data.frame())     #a data.frame with nothing in it:      list
typeof(data.frame(c(3))) #a data.frame with a double in it:     list
typeof(c("foobar"))      #a vector containing only strings:     character
typeof(pi)               #builtin expression for pi:            double

#OK, I'm starting to get irritated, however, I am also longsuffering:
typeof(1.66)             #a single numeric with mantissa:       double
typeof(1.66L)            #a double with L postfixed             double
typeof(c("foobar"))      #a vector containing only strings:     character
typeof(c(5L, 6L))        #a vector containing only integers:    integer
typeof(c(1.5, 2.5))      #a vector containing only doubles:     double
typeof(c(1.5, 2.5))      #a vector containing only doubles:     double
typeof(c(TRUE, FALSE))   #a vector containing only logicals:    logical

#R is really cramping my style, killing my high, irritation is increasing:
typeof(factor())         #an empty factor has default type:     integer
typeof(factor(3.14))     #a factor containing doubles:          integer
typeof(factor(T, F))     #a factor containing logicals:         integer
typeof(Sys.Date())       #builtin R dates:                      double
typeof(hms::hms(3600))   #hour minute second timestamp          double
typeof(c(T, F))          #T and F are builtins:                 logical
typeof(1:10)             #a builtin sequence of numerics:       integer
typeof(NA)               #The builtin value not available:      logical

#The R coolaid punchbowl has been spiked: stay frosty and keep your head low:
typeof(c(list(T)))       #a vector of lists of logical:         list
typeof(list(c(T)))       #a list of vectors of logical:         list
typeof(c(T, 3.14))       #a vector of logicals and doubles:     double
typeof(c(3.14, "foo"))   #a vector of doubles and characters:   character
typeof(c("foo",list(T))) #a vector of strings and lists:        list
typeof(list("foo",c(T))) #a list of strings and vectors:        list
typeof(TRUE + 5L)        #a logical plus an integer:            integer
typeof(c(TRUE, 5L)[1])   #The true is coerced to 1              integer
typeof(c(c(2i), TRUE)[1])#logical coerced to complex:           complex
typeof(c(NaN, 'batman')) #NaN's in a vector don't dominate:     character
typeof(5 && 4)           #doubles are coerced by order of &&    logical
typeof(8 < 'foobar')     #string and double is coerced          logical
typeof(list(4, T)[[1]])  #a list retains type at every index:   double
typeof(list(4, T)[[2]])  #a list retains type at every index:   logical
typeof(2 ** 5)           #result of exponentiation              double
typeof(0E0)              #exponential lol notation              double
typeof(0x3fade)          #hexidecimal                           double
typeof(paste(3, '3'))    #paste promotes types to string        character
typeof(3 +)           #R pukes on unicode                    error
typeof(iconv("a", "latin1", "UTF-8")) #UTF-8 characters         character
typeof(5 == 5)           #result of a comparison:               logical

So erhalten Sie die Klasse einer Variablen, die Sie in R haben

Die R- Funktionclass hat eine Tendenz, Ihnen den Typ des Containers oder der Struktur zu geben, die beispielsweise Ihre Typen einkapseln.

library(tibble)

#expression            notes                                    class
#--------------------- ---------------------------------------- ---------
class(matrix(1:10))     #a matrix of doubles has a class:       matrix
class(factor("hi"))     #factor of items is:                    factor
class(TRUE)             #a single boolean:                      logical
class(1L)               #a single numeric with L postfixed:     integer
class("foobar")         #A single string in double quotes:      character
class(1)                #a single numeric:                      numeric
class(list(5,6,7))      #a list of numeric:                     list
class(2i)               #an imaginary                           complex
class(data.frame())     #a data.frame with nothing in it:       data.frame
class(Sys.Date())       #builtin R dates:                       Date
class(sapply)           #a function is                          function
class(charToRaw("hi"))  #convert string to raw:                 raw
class(array("hi"))      #array of items is:                     array

#So far so good, but those who wish to keep their sanity go no further
class(5 + 5L)           #double + integer is coerced:          numeric
class(c())              #an empty vector has no class:         NULL
class(!5)               #a bang before a double:               logical
class(Inf)              #infinity has a class:                 numeric
class(c(5,6,7))         #a vector containing only doubles:     numeric
class(c(c(TRUE)))       #a vector of vector of logicals:       logical

#Strangeness ahead, there be dragons: step carefully:
class(substr("abc",2,2))#a string at index 2 which is 'b' is:  character
class(c(5L,6L,7L))      #a vector containing only integers:    integer
class(c(NA,NA,NA))      #a vector containing only NA:          logical
class(data.frame(c(3))) #a data.frame with a double in it:     data.frame
class(c("foobar"))      #a vector containing only strings:     character
class(pi)               #builtin expression for pi:            numeric

#OK, I'm starting to get irritated, however, I am also longsuffering:
class(1.66)             #a single numeric with mantissa:       numeric
class(1.66L)            #a double with L postfixed             numeric
class(c("foobar"))      #a vector containing only strings:     character
class(c(5L, 6L))        #a vector containing only integers:    integer
class(c(1.5, 2.5))      #a vector containing only doubles:     numeric
class(c(TRUE, FALSE))   #a vector containing only logicals:    logical

#R is really cramping my style, killing my high, irritation is increasing:
class(factor())       #an empty factor has default class:      factor
class(factor(3.14))   #a factor containing doubles:            factor
class(factor(T, F))   #a factor containing logicals:           factor
class(hms::hms(3600)) #hour minute second timestamp            hms difftime
class(c(T, F))        #T and F are builtins:                   logical
class(1:10)           #a builtin sequence of numerics:         integer
class(NA)             #The builtin value not available:        logical

#The R coolaid punchbowl has been spiked: stay frosty and keep your head low:
class(c(list(T)))       #a vector of lists of logical:         list
class(list(c(T)))       #a list of vectors of logical:         list
class(c(T, 3.14))       #a vector of logicals and doubles:     numeric
class(c(3.14, "foo"))   #a vector of doubles and characters:   character
class(c("foo",list(T))) #a vector of strings and lists:        list
class(list("foo",c(T))) #a list of strings and vectors:        list
class(TRUE + 5L)        #a logical plus an integer:            integer
class(c(TRUE, 5L)[1])   #The true is coerced to 1              integer
class(c(c(2i), TRUE)[1])#logical coerced to complex:           complex
class(c(NaN, 'batman')) #NaN's in a vector don't dominate:     character
class(5 && 4)           #doubles are coerced by order of &&    logical
class(8 < 'foobar')     #string and double is coerced          logical
class(list(4, T)[[1]])  #a list retains class at every index:  numeric
class(list(4, T)[[2]])  #a list retains class at every index:  logical
class(2 ** 5)           #result of exponentiation              numeric
class(0E0)              #exponential lol notation              numeric
class(0x3fade)          #hexidecimal                           numeric
class(paste(3, '3'))     #paste promotes class to string       character
class(3 +)           #R pukes on unicode                   error
class(iconv("a", "latin1", "UTF-8")) #UTF-8 characters         character
class(5 == 5)           #result of a comparison:               logical

Holen Sie sich die Daten storage.modeIhrer Variablen

Wenn eine R-Variable auf die Festplatte geschrieben wird, ändert sich das Datenlayout erneut und wird als Datenvariable bezeichnetstorage.mode . Die Funktion storage.mode(...)zeigt diese Informationen auf niedriger Ebene an: siehe Modus, Klasse und Typ von R-Objekten . Sie sollten sich keine Gedanken über den Speichermodus von R machen müssen, es sei denn, Sie versuchen, Verzögerungen zu verstehen, die durch Roundtrip-Casts / Zwänge verursacht werden, die beim Zuweisen und Lesen von Daten auf und von der Festplatte auftreten.

Ideologie rund um Rs Triaden-Typisierungssystem:

Rs Enten-Typisierungssystem weist Unsicherheit auf. Betrachten Sie als Analogie einen Keramikbecher, der zum Halten einer Flüssigkeit oder als Projektil wie ein Baseball verwendet werden kann. Der Zweck des Bechers hängt von seinen verfügbaren Eigenschaften und der auf ihn einwirkenden Funktion ab. Diese Fließfähigkeit des Typs ermöglicht es Programmierern, jede Art von Ausgabe von einer Funktion in eine andere Funktion umzuleiten, und R wird große Anstrengungen unternehmen, um zu versuchen, Ihre Gedanken zu lesen und etwas Vernünftiges zu tun.

Die Idee ist, dass neue Programmierer, wenn sie R-Programme über Brownsche Bewegung schreiben, wie sie wollen, versuchen, a googah.blimflargin a zu übergeben vehicle.subspaceresponder(...). Anstatt einen Tippfehler zu kotzen, macht das R-Programm Gymnastik, um den Typ zu transformieren und dann etwas überraschend Nützliches zu tun. Der neue Programmierer veröffentlicht den Code in seinem Blog und sagt: "Sehen Sie sich diese enorme Sache an, die ich mit 3 Zeilen R-Code gemacht habe! Ich habe keine Ahnung, woher er weiß, was zu tun ist, aber er tut es!"


Wie kann man zum Beispiel ds <- c (3,4,5,5,3) identifizieren - dass "ds" genau ein Vektor mit einem numerischen Typ ist?
Max Usanin

1
Erstellen Sie Ihre eigene benutzerdefinierte R-Funktion, die Sie in Ihrer Toolbox behalten, die einen Parameter x annimmt. Verwenden Sie innerhalb der Funktion if-Anweisungen, um zu überprüfen, ob der Typ (x) numerisch ist und ob die Klasse (x) ein Vektor ist. Wenn ja, drucken Sie die Zeichenfolge: "x ist genau ein Vektor mit einem numerischen Typ". R wird Ihnen in dieser Abteilung nicht weiterhelfen, da dieses Triaden-Typisierungssystem unendlich komplex ist. Eine Typanalyse ist nicht möglich. Sobald Sie alle Typen definieren, definiert jemand einen neuen. Das R-Typisierungssystem ist bei weitem das schlechteste, das ich je in einer Sprache gesehen habe. Es ist ein Deponiefeuer.
Eric Leschinski

6

Sie können die Klasse (x) verwenden, um den Variablentyp zu überprüfen. Wenn alle Variablentypen eines Datenrahmens überprüft werden sollen, kann sapply (x, class) verwendet werden.


4
> mtcars %>% 
+     summarise_all(typeof) %>% 
+     gather
    key  value
1   mpg double
2   cyl double
3  disp double
4    hp double
5  drat double
6    wt double
7  qsec double
8    vs double
9    am double
10 gear double
11 carb double

Ich versuche classund typeoffunktioniert, aber alles schlägt fehl.


1

Hier ist eines meiner Toolkit-Spielzeuge, das im Wesentlichen das Gegenteil von dem ist, was Sie wollten:

 lstype<-function(type='closure'){
inlist<-ls(.GlobalEnv)
if (type=='function') type <-'closure'
typelist<-sapply(sapply(inlist,get),typeof)
return(names(typelist[typelist==type]))
}

0

lapply (your_dataframe, class) gibt Ihnen so etwas wie:

$ tikr [1] "Faktor"

$ Date [1] "Date"

$ Open [1] "numerisch"

$ High [1] "numerisch"

... etc.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.