Dapatkan tipe semua variabel

118

Di R, saya ingin mengambil daftar variabel global di akhir skrip saya dan mengulanginya. Ini kode saya

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

Masalah saya adalah itu typeof(i) selalu kembali charactermeskipun variabel adan cbukan variabel karakter. Bagaimana saya bisa mendapatkan tipe variabel asli di dalam loop for?

Konrad Rudolph
sumber
Catatan untuk orang-orang yang membaca pertanyaan ini: typeof()memberikan informasi yang sangat umum tentang bagaimana objek disimpan dalam memori. Untuk sebagian besar kasus penggunaan, jika Anda ingin mengetahui informasi yang baik tentang variabel x, Anda akan mendapatkan informasi yang lebih berguna dari class(x), is(x)atau str(x)(di urutan berapa banyak detail yang mereka berikan). Lihat jawaban Eric di bawah ini untuk contoh apa yang typeof()memberi tahu Anda: faktor adalah integer; daftar, bingkai data, objek model, objek tingkat lanjut lainnya hanya list...
Gregor Thomas

Jawaban:

109

Anda perlu menggunakan getuntuk mendapatkan nilai daripada nama karakter objek seperti yang dikembalikan oleh ls:

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

Atau, untuk masalah yang disajikan, Anda mungkin ingin menggunakan eapply:

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

$a
[1] "double"

$b
[1] "character"

$c
[1] "list"
James
sumber
Bekerja dengan sempurna. Apakah Anda tahu jika ada penalti kinerja jika get () digunakan untuk menemukan tipe dari beberapa bingkai data besar yang mungkin ada dalam daftar variabel yang dikembalikan oleh objek ()?
1
getmemiliki kritik dan saya membayangkan eapplyakan lebih cepat dari loop yang ditafsirkan. Tapi hanya ada satu cara untuk mengetahuinya ...
James
17

Cara mendapatkan tipe variabel saat disembunyikan di bawah objek global:

Semua yang Anda butuhkan ada di manual R tentang tipe dasar: https://cran.r-project.org/doc/manuals/R-lang.html#Basic-types

object()Kebutuhan Anda untuk ditembus get(...)sebelum Anda dapat melihat ke dalam. Contoh:

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

Bagaimana mendapatkan tipe variabel yang Anda miliki di R

R fungsitypeof memiliki bias untuk memberikan jenis di kedalaman maksimum, misalnya.

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

Cara mendapatkan kelas variabel yang Anda miliki di R

R fungsiclass memiliki bias untuk memberikan jenis wadah atau struktur encapsulating jenis Anda, misalnya.

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

Dapatkan data storage.modevariabel Anda

Ketika variabel R ditulis ke disk, tata letak data berubah lagi, dan disebut datastorage.mode . Fungsi storage.mode(...)mengungkapkan informasi ini tingkat rendah: lihat Mode, Kelas, dan Jenis objek R . Anda tidak perlu khawatir tentang R's storage.mode kecuali Anda mencoba memahami penundaan yang disebabkan oleh pemaksaan / pemaksaan round trip yang terjadi saat menetapkan dan membaca data ke dan dari disk.

Ideologi seputar sistem pengetikan triad R:

Sistem pengetikan bebek R memiliki ketidakpastian di dalamnya. Sebagai analogi, pertimbangkan cangkir keramik, dapat digunakan untuk menampung cairan, atau digunakan sebagai proyektil seperti bola bisbol. Tujuan dari cangkir tergantung pada sifat yang tersedia dan fungsi yang bekerja padanya. Jenis fluiditas ini memungkinkan kelonggaran yang lebih besar bagi pemrogram untuk mengarahkan semua jenis keluaran dari satu fungsi ke fungsi lain, dan R akan berusaha keras untuk mencoba membaca pikiran Anda dan melakukan sesuatu yang masuk akal.

Idenya adalah bahwa ketika programmer pemula menulis program R melalui gerakan Brownian, sebagaimana yang mereka inginkan, mereka mencoba untuk memasukkan a googah.blimflargke vehicle.subspaceresponder(...). Alih-alih memuntahkan kesalahan jenis, program R melakukan senam untuk mengubah jenis dan kemudian melakukan sesuatu yang sangat berguna. Pemrogram pemula memposting kode di blognya dan berkata "lihat hal luar biasa yang saya lakukan dengan 3 baris kode R! Saya tidak tahu bagaimana ia tahu apa yang harus dilakukan, tetapi ternyata berhasil!"

Eric Leschinski
sumber
Bagaimana cara mengidentifikasi misalnya ds <- c (3,4,5,5,3) - bahwa "ds" persis vektor dengan tipe numerik?
Max Usanin
1
Buat fungsi R kustom Anda sendiri yang Anda simpan di kotak alat yang mengambil parameter x. Di dalam fungsi gunakan pernyataan if untuk memeriksa apakah tipe (x) adalah numerik dan jika kelas (x) adalah vektor. Jika demikian, cetak string: "x persis sebuah vektor dengan tipe numerik". R tidak akan membantu Anda di departemen ini karena sistem pengetikan triad ini memiliki kompleksitas tak terbatas, analisis tipe tidak mungkin, segera setelah Anda menentukan semua tipe, seseorang mendefinisikan yang baru. Sistem pengetikan R sejauh ini adalah yang terburuk yang pernah saya lihat dari bahasa apa pun. Ini kebakaran TPA.
Eric Leschinski
6

Anda dapat menggunakan class (x) untuk memeriksa tipe variabel. Jika persyaratannya adalah untuk memeriksa semua jenis variabel dari bingkai data maka sapply (x, class) dapat digunakan.

GauravS
sumber
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

Saya mencoba classdan typeofberfungsi, tetapi semuanya gagal.

Jiaxiang
sumber
1

Dirancang untuk melakukan kebalikan dari apa yang Anda inginkan, inilah salah satu mainan toolkit saya:

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

lapply (your_dataframe, class) memberi Anda sesuatu seperti:

$ tikr [1] "faktor"

$ Date [1] "Date"

$ Terbuka [1] "numerik"

$ Tinggi [1] "numerik"

... dll.

Dimitar Nentchev
sumber