Ottieni il tipo di tutte le variabili


118

In R, mi piacerebbe recuperare un elenco di variabili globali alla fine del mio script e iterare su di esse. Ecco il mio codice

#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'
}

Il mio problema è che typeof(i)ritorna sempre characteranche se variabile ae cnon sono variabili carattere. Come posso ottenere il tipo originale di variabile all'interno del ciclo for?


Nota per le persone che leggono questa domanda: typeof()fornisce un'informazione molto generica su come l'oggetto viene archiviato in memoria. Per la maggior parte casi di utilizzo, se volete sapere una buona informazione su una variabile x, si otterrà le informazioni più utili da class(x), is(x)o str(x)(in ordine di quantità di dettagli che forniscono). Vedi la risposta di Eric di seguito per esempi di ciò che typeof()ti dice: i fattori sono integer; elenchi, frame di dati, oggetti modello, altri oggetti avanzati sono solo list...
Gregor Thomas

Risposte:


109

È necessario utilizzare getper ottenere il valore anziché il nome del carattere dell'oggetto restituito da ls:

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

In alternativa, per il problema presentato potresti voler utilizzare eapply:

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

$a
[1] "double"

$b
[1] "character"

$c
[1] "list"

Fatti lavorare perfettamente. Sapete se c'è qualche penalità nelle prestazioni se get () viene utilizzato per trovare il tipo di diversi frame di dati di grandi dimensioni che possono essere presenti nell'elenco delle variabili restituito da objects ()?

1
getha i suoi critici e immagino che eapplysarebbe più veloce di un loop interpretato. Ma c'è solo un modo per scoprirlo ...
James

17

Come ottenere il tipo di variabile quando è nascosto sotto un oggetto globale:

Tutto ciò di cui hai bisogno è nel manuale R sui tipi di base: https://cran.r-project.org/doc/manuals/R-lang.html#Basic-types

Il tuo object()bisogno di essere penetrati get(...)prima di poter vedere all'interno. Esempio:

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

Come ottenere il tipo di variabile che hai in R

La funzionetypeof R ha un bias per darti il ​​tipo alla massima profondità, per esempio.

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

Come ottenere la classe di una variabile che hai in R

La funzioneclass R ha un pregiudizio per darti il ​​tipo di contenitore o struttura che incapsula i tuoi tipi, per esempio.

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

Ottieni i dati storage.mode della tua variabile

Quando una variabile R viene scritta su disco, il layout dei dati cambia ancora e viene chiamato dei datistorage.mode . La funzione storage.mode(...)rivela queste informazioni di basso livello: vedere gli oggetti Modalità, Classe e Tipo di R. . Non dovresti preoccuparti della modalità di archiviazione di R a meno che tu non stia cercando di comprendere i ritardi causati da cast / coercizioni di andata e ritorno che si verificano durante l'assegnazione e la lettura dei dati da e verso il disco.

Ideologia intorno al sistema di tipizzazione della triade di R:

Il sistema di dattilografia di R ha incertezza. Per analogia, considera una tazza di ceramica, può essere usata per contenere un liquido o usata come proiettile come una palla da baseball. Lo scopo della tazza dipende dalle sue proprietà disponibili e dalla funzione che agisce su di esso. Questa fluidità di tipo consente ai programmatori un maggiore margine di manovra per reindirizzare qualsiasi tipo di output da una funzione a un'altra funzione, e R farà di tutto per cercare di leggere la tua mente e fare qualcosa di ragionevole.

L'idea è che quando i programmatori principianti scrivono programmi R tramite il moto browniano, come faranno, tentano di passare a googah.blimflargin a vehicle.subspaceresponder(...). Invece di vomitare un errore di tipo, il programma R fa ginnastica per trasformare il tipo e poi fare qualcosa di sorprendentemente utile. Il programmatore principiante pubblica il codice sul suo blog e dice "guarda questa cosa tremenda che ho fatto con 3 righe di codice R! Non ho idea di come sappia cosa fare, ma lo fa!"


come identificare ad esempio ds <- c (3,4,5,5,3) - che "ds" è esattamente un vettore con il tipo di contenuto numerico?
Max Usanin

1
Crea la tua funzione R personalizzata che tieni nella tua cassetta degli attrezzi che accetta un parametro x. All'interno della funzione utilizzare le istruzioni if ​​per verificare se il tipo di (x) è numerico e se la classe (x) è un vettore. In tal caso, stampare la stringa: "x è esattamente un vettore con un tipo numerico". R non ti aiuterà in questo reparto perché questo sistema di digitazione a triade ha una complessità infinita, l'analisi del tipo è impossibile, non appena definisci tutti i tipi, qualcuno ne definisce uno nuovo. Il sistema di digitazione R è di gran lunga il peggiore che abbia mai visto di qualsiasi lingua. È un incendio in discarica.
Eric Leschinski

6

Puoi usare class (x) per controllare il tipo di variabile. Se il requisito è controllare il tipo di tutte le variabili di un frame di dati, è possibile utilizzare sapply (x, class).


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

Provo classe typeoffunziona, ma tutto fallisce.


1

Progettato per fare essenzialmente l'inverso di quello che volevi, ecco uno dei miei giocattoli del toolkit:

 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) ti dà qualcosa come:

$ tikr [1] "fattore"

$ Date [1] "Data"

$ Apri [1] "numerico"

$ Alto [1] "numerico"

... eccetera.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.