获取所有变量的类型

在 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,即使变量 ac不是字符变量。如何在 for 循环中获得变量的原始类型?

361774 次浏览

您需要使用 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"

设计的目的基本上与你想要的相反,这是我的一个工具箱玩具:

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

可以使用 class (x)检查变量类型。如果需要检查数据框架的所有变量类型,那么可以使用 sapplication (x,class)。

R/Rscript 没有具体的数据类型。

R 解释器有一个 Duck 类型的内存分配系统。没有内置的方法来告诉您指向内存的指针的数据类型。Duck 键入是为了提高速度,但结果证明这是个坏主意,因为现在的语句如: print(is.integer(5))返回 FALSE,is.integer(as.integer(5))返回 TRUE。想想看。

基本类型手册: 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
}

Typeof (...)探测内存变量指针:

例如,R 功能 typeof有一个偏差,可以在最大深度给出类型。

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


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


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


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


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


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

Class (...)探测指向内存的变量指针:

例如,R 功能 class有一个偏好,即为您提供封装类型的容器或结构的类型。

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


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


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


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


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


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 的 storage.mode,除非您试图理解在向磁盘分配和从磁盘读取数据时发生的往返强制转换/强制执行所导致的延迟。

演示: R/Rscript gettype(your_variable):

运行这个 R 代码,然后根据自己的目的对其进行调整,这样就可以很好地猜测它是什么类型。

get_type <- function(variable){
sz <- as.integer(length(variable)) #length of your variable
tof <- typeof(variable)            #typeof your variable
cls <- class(variable)             #class of your variable
isc <- is.character(variable)      #what is.character() has to say about it.
d <- dim(variable)                 #dimensions of your variable
isv <- is.vector(variable)
if (is.matrix(variable)){
d <- dim(t(variable))             #dimensions of your matrix
}
#observations ----> datatype
if (sz>=1 && tof == "logical" && cls == "logical" && isv == TRUE){ return("vector of logical") }
if (sz>=1 && tof == "integer" && cls == "integer" ){ return("vector of integer") }
if (sz==1 && tof == "double"  && cls == "Date" ){ return("Date") }
if (sz>=1 && tof == "raw"     && cls == "raw" ){ return("vector of raw") }
if (sz>=1 && tof == "double"  && cls == "numeric" ){ return("vector of double") }
if (sz>=1 && tof == "double"  && cls == "array" ){ return("vector of array of double") }
if (sz>=1 && tof == "character"  && cls == "array" ){ return("vector of array of character") }
if (sz>=0 && tof == "list"       && cls == "data.frame" ){ return("data.frame") }
if (sz>=1 && isc == TRUE         && isv == TRUE){ return("vector of character") }
if (sz>=1 && tof == "complex"    && cls == "complex" ){ return("vector of complex") }
if (sz==0 && tof == "NULL"       && cls == "NULL" ){ return("NULL") }
if (sz>=0 && tof == "integer"    && cls == "factor" ){ return("factor") }
if (sz>=1 && tof == "double"     && cls == "numeric" && isv == TRUE){ return("vector of double") }
if (sz>=1 && tof == "double"     && cls == "matrix"){ return("matrix of double") }
if (sz>=1 && tof == "character"  && cls == "matrix"){ return("matrix of character") }
if (sz>=1 && tof == "list"       && cls == "list" && isv == TRUE){ return("vector of list") }
if (sz>=1 && tof == "closure"    && cls == "function" && isv == FALSE){ return("closure/function") }
return("it's pointer to memory, bruh")
}
assert <- function(a, b){
if (a == b){
cat("P")
}
else{
cat("\nFAIL!!!  Sniff test:\n")
sz <- as.integer(length(variable))   #length of your variable
tof <- typeof(variable)              #typeof your variable
cls <- class(variable)               #class of your variable
isc <- is.character(variable)        #what is.character() has to say about it.
d <- dim(variable)                   #dimensions of your variable
isv <- is.vector(variable)
if (is.matrix(variable)){
d <- dim(t(variable))                   #dimensions of your variable
}
if (!is.function(variable)){
print(paste("value: '", variable, "'"))
}
print(paste("get_type said: '", a, "'"))
print(paste("supposed to be: '", b, "'"))
 

cat("\nYour pointer to memory has properties:\n")
print(paste("sz: '", sz, "'"))
print(paste("tof: '", tof, "'"))
print(paste("cls: '", cls, "'"))
print(paste("d: '", d, "'"))
print(paste("isc: '", isc, "'"))
print(paste("isv: '", isv, "'"))
quit()
}
}
#these asserts give a sample for exercising the code.
assert(get_type(TRUE),      "vector of logical")  #everything is a vector in R by default.
assert(get_type(c(TRUE)),   "vector of logical")  #c() just casts to vector
assert(get_type(c(c(TRUE))),"vector of logical")  #casting vector multiple times does nothing
assert(get_type(!5),        "vector of logical")  #bang inflicts 'not truth-like'
assert(get_type(1L),              "vector of integer")   #naked integers are still vectors of 1
assert(get_type(c(1L, 2L)),       "vector of integer")   #Longs are not doubles
assert(get_type(c(1L, c(2L, 3L))),"vector of integer")   #nested vectors of integers
assert(get_type(c(1L, c(TRUE))),  "vector of integer")   #logicals coerced to integer
assert(get_type(c(FALSE, c(1L))), "vector of integer")   #logicals coerced to integer
assert(get_type("foobar"),        "vector of character")    #character here means 'string'
assert(get_type(c(1L, "foobar")), "vector of character")    #integers are coerced to string
assert(get_type(5),           "vector of double")
assert(get_type(5 + 5L),      "vector of double")
assert(get_type(Inf),         "vector of double")
assert(get_type(c(5,6,7)),    "vector of double")
assert(get_type(NaN),           "vector of double")
assert(get_type(list(5)),       "vector of list")    #your list is in a vector.
assert(get_type(list(5,6,7)),   "vector of list")
assert(get_type(c(list(5,6,7))),"vector of list")
assert(get_type(list(c(5,6),T)),"vector of list")    #vector of list of vector and logical
assert(get_type(list(5,6,7)),   "vector of list")
assert(get_type(2i),            "vector of complex")
assert(get_type(c(2i, 3i, 4i)), "vector of complex")
assert(get_type(c()),            "NULL")
assert(get_type(data.frame()),   "data.frame")
assert(get_type(data.frame(4,5)),"data.frame")
assert(get_type(Sys.Date()),     "Date")
assert(get_type(sapply),         "closure/function")
assert(get_type(charToRaw("hi")),"vector of raw")
assert(get_type(c(charToRaw("a"), charToRaw("b"))), "vector of raw")
assert(get_type(array(4)),       "vector of array of double")
assert(get_type(array(4,5)),     "vector of array of double")
assert(get_type(array("hi")),    "vector of array of character")
assert(get_type(factor()),       "factor")
assert(get_type(factor(3.14)),   "factor")
assert(get_type(factor(TRUE)),   "factor")
assert(get_type(matrix(3,4,5)),  "matrix of double")
assert(get_type(as.matrix(5)),   "matrix of double")
assert(get_type(matrix("yatta")),"matrix of character")

我在这里加入了一个 C + +/Java/Python 的思想体系,它让我了解了内存最常见的样子。R 三合一打字系统就像试图把意大利面钉在墙上,<-<<-会在你最不怀疑的时候把你的矩阵打包成一个列表。正如老鸭打字说: 如果它像鸭子一样摇摆,如果它像鸭子一样嘎嘎叫,如果它有羽毛,那么它就是鸭子。

> 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

我尝试了 classtypeof函数,但都失败了。

Lapplication (your _ dataframe,class)为您提供如下内容:

$tikr [1]“因素”

$日期 [1]“约会”

$打开 [1]“数字”

$高 [1]“数字”

等等。