รับประเภทของตัวแปรทั้งหมด


118

ใน R ฉันต้องการดึงรายการตัวแปรส่วนกลางที่ส่วนท้ายของสคริปต์ของฉันและทำซ้ำ นี่คือรหัสของฉัน

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

ปัญหาของฉันคือtypeof(i)ผลตอบแทนเสมอcharacterแม้ว่าตัวแปรaและcไม่ใช่ตัวแปรอักขระ ฉันจะรับตัวแปรประเภทดั้งเดิมภายใน for loop ได้อย่างไร


หมายเหตุสำหรับคนที่อ่านคำถามนี้: typeof()ให้ข้อมูลทั่วไปเกี่ยวกับวิธีจัดเก็บวัตถุในหน่วยความจำ สำหรับกรณีการใช้งานมากที่สุดถ้าคุณต้องการทราบข้อมูลดีๆเกี่ยวกับตัวแปรที่xคุณจะได้รับข้อมูลที่เป็นประโยชน์เพิ่มเติมจากclass(x), is(x)หรือstr(x)(เรียงตามลำดับวิธีการรายละเอียดมากที่พวกเขามีให้) ดูคำตอบของ Eric ด้านล่างสำหรับตัวอย่างสิ่งที่typeof()บอกคุณ: ปัจจัยคือinteger; รายการเฟรมข้อมูลวัตถุแบบจำลองวัตถุขั้นสูงอื่น ๆ เป็นเพียงlist...
Gregor Thomas

คำตอบ:


109

คุณต้องใช้getเพื่อรับค่าแทนชื่ออักขระของวัตถุที่ส่งคืนโดยls:

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

หรือสำหรับปัญหาที่นำเสนอคุณอาจต้องการใช้eapply:

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

$a
[1] "double"

$b
[1] "character"

$c
[1] "list"

ทำงานได้อย่างสมบูรณ์แบบ คุณรู้หรือไม่ว่ามีการลงโทษด้านประสิทธิภาพหากใช้ get () เพื่อค้นหาประเภทของเฟรมข้อมูลขนาดใหญ่หลาย ๆ เฟรมซึ่งอาจมีอยู่ในรายการตัวแปรที่ส่งคืนโดยอ็อบเจ็กต์ ()

1
getมีนักวิจารณ์และฉันคิดว่าeapplyมันจะเร็วกว่าลูปที่ตีความ แต่มีทางเดียวเท่านั้นที่จะค้นพบ ...
ยากอบ

17

วิธีรับประเภทของตัวแปรเมื่อซ่อนอยู่ใต้วัตถุส่วนกลาง:

ทุกสิ่งที่คุณต้องการอยู่ในคู่มือ R ประเภทพื้นฐาน: https://cran.r-project.org/doc/manuals/R-lang.html#Basic-types

คุณobject()ต้องเจาะเข้าไปget(...)ก่อนจึงจะเห็นภายใน ตัวอย่าง:

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

วิธีรับประเภทของตัวแปรที่คุณมีใน R

ฟังก์ชันtypeof R มีอคติเพื่อให้คุณระบุประเภทที่ความลึกสูงสุดตัวอย่างเช่น

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

วิธีรับคลาสของตัวแปรที่คุณมีใน R

ฟังก์ชันclass R มีอคติในการระบุประเภทของคอนเทนเนอร์หรือโครงสร้างที่ห่อหุ้มประเภทของคุณเช่น

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

รับข้อมูลstorage.modeของตัวแปรของคุณ

เมื่อตัวแปร R ถูกเขียนไปยังดิสก์รูปแบบข้อมูลที่มีการเปลี่ยนแปลงอีกครั้งและถูกเรียกว่าข้อมูลของ storage.modeฟังก์ชั่นstorage.mode(...)แสดงให้เห็นข้อมูลในระดับนี้ต่ำ: ดูโหมดระดับและประเภทของวัตถุ R คุณไม่จำเป็นต้องกังวลเกี่ยวกับโหมดจัดเก็บข้อมูลของ R เว้นแต่คุณจะพยายามทำความเข้าใจกับความล่าช้าที่เกิดจากการส่งแบบไปกลับ / การบีบบังคับที่เกิดขึ้นเมื่อกำหนดและอ่านข้อมูลเข้าและออกจากดิสก์

อุดมการณ์เกี่ยวกับระบบการพิมพ์สามตัวของ R:

ระบบการพิมพ์เป็ดของ R มีความไม่แน่นอนอยู่ในนั้น ในการเปรียบเทียบลองพิจารณาถ้วยเซรามิกมันสามารถใช้สำหรับใส่ของเหลวหรือใช้เป็นกระสุนปืนได้เช่นเดียวกับเบสบอล วัตถุประสงค์ของถ้วยขึ้นอยู่กับคุณสมบัติที่มีอยู่และหน้าที่ที่ทำ ความลื่นไหลของประเภทนี้ช่วยให้โปรแกรมเมอร์สามารถเปลี่ยนเส้นทางเอาต์พุตชนิดใดก็ได้จากฟังก์ชันหนึ่งไปยังฟังก์ชันอื่นและ R จะพยายามอ่านความคิดของคุณและทำสิ่งที่สมเหตุสมผล

แนวคิดก็คือเมื่อโปรแกรมเมอร์มือใหม่เขียนโปรแกรม R ผ่าน Brownian motion ตามที่ต้องการพวกเขาจะพยายามส่งgoogah.blimflargไฟล์vehicle.subspaceresponder(...). แทนที่จะอ้วกข้อผิดพลาดประเภทโปรแกรม R ทำยิมนาสติกเพื่อเปลี่ยนประเภทจากนั้นทำสิ่งที่มีประโยชน์อย่างน่าประหลาดใจ โปรแกรมเมอร์มือใหม่โพสต์โค้ดในบล็อกของเขาและบอกว่า "ดูสิ่งที่ยิ่งใหญ่นี้ที่ฉันทำด้วยรหัส R 3 บรรทัดฉันไม่รู้ว่ามันรู้ได้อย่างไรว่าต้องทำอย่างไร แต่มันทำได้!"


วิธีระบุตัวอย่างเช่น ds <- c (3,4,5,5,3) - "ds" เป็นเวกเตอร์ที่มีประเภทตัวเลขหรือไม่
Max Usanin

1
สร้างฟังก์ชัน R ของคุณเองที่คุณเก็บไว้ในกล่องเครื่องมือของคุณที่รับพารามิเตอร์ x ภายในฟังก์ชันใช้คำสั่ง if เพื่อตรวจสอบว่า typeof (x) เป็นตัวเลขหรือไม่และถ้าคลาส (x) เป็นเวกเตอร์ ในกรณีนี้ให้พิมพ์สตริง: "x คือเวกเตอร์ที่มีประเภทตัวเลข" R จะไม่ช่วยคุณในแผนกนี้เนื่องจากระบบการพิมพ์สามตัวนี้มีความซับซ้อนไม่สิ้นสุดการวิเคราะห์ประเภทเป็นไปไม่ได้ทันทีที่คุณกำหนดประเภททั้งหมดจะมีคนกำหนดประเภทใหม่ ระบบการพิมพ์ R นั้นแย่ที่สุดที่ฉันเคยเห็นในภาษาใด ๆ มันเป็นไฟที่ฝังกลบ
Eric Leschinski

6

คุณสามารถใช้คลาส (x) เพื่อตรวจสอบประเภทตัวแปร หากความต้องการคือการตรวจสอบประเภทตัวแปรทั้งหมดของ data frame สามารถใช้ 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

ฉันพยายามclassและtypeofทำงาน แต่ทั้งหมดล้มเหลว


1

ออกแบบมาเพื่อทำสิ่งที่ตรงกันข้ามกับสิ่งที่คุณต้องการเป็นหลักนี่คือของเล่นชุดเครื่องมือของฉัน:

 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) ให้สิ่งที่ต้องการ:

$ tikr [1] "ตัวประกอบ"

$ Date [1] "วันที่"

$ เปิด [1] "ตัวเลข"

$ สูง [1] "ตัวเลข"

... ฯลฯ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.