对“模式”,“阶级”和“types”的事物types进行全面考察是不够的

语言R混淆了我。 实体有模式 ,但即使这样也不足以充分描述实体。

这个答案说

在R中,每个“对象”都有一个模式和一个类。

所以我做了这些实验:

> class(3) [1] "numeric" > mode(3) [1] "numeric" > typeof(3) [1] "double" 

到目前为止还不够公平,但是我传递了一个向量:

 > mode(c(1,2)) [1] "numeric" > class(c(1,2)) [1] "numeric" > typeof(c(1,2)) [1] "double" 

这没有意义。 当然,整数向量应该有一个不同的类或不同的模式,而不是一个整数? 我的问题是:

  • R中的所有东西都有(正好一个) 吗?
  • R中的所有东西都有(恰好一种) 模式吗?
  • 如果有的话,“typeof”告诉我们什么?
  • 还需要其他什么信息来完整描述实体? (例如,“vector性”存储在哪里?)

更新 :显然,文字3只是一个长度为1的向量。没有标量。 OK但是…我尝试mode("string")并得到"character" ,导致我认为一个string是一个字符的vector。 但如果这是真的,那么这应该是真实的,但它不是! c('h','i') == "hi"

我同意R中的types系统是相当奇怪的。 这样做的原因是它已经发展了很长一段时间。

请注意,您错过了另一个types函数storage.mode和另一个类类函数oldClass

因此, modestorage.mode是旧式types( storage.mode更准确),而typeof则是更新,更精确的版本。

 mode(3L) # numeric storage.mode(3L) # integer storage.mode(`identical`) # function storage.mode(`if`) # function typeof(`identical`) # closure typeof(`if`) # special 

然后class是一个完全不同的故事。 class主要只是对象的class属性(这正是oldClass返回的)。 但是当class属性没有设置的时候, classfunction是由对象types和dim属性组成的。

 oldClass(3L) # NULL class(3L) # integer class(structure(3L, dim=1)) # array class(structure(3L, dim=c(1,1))) # matrix class(list()) # list class(structure(list(1), dim=1)) # array class(structure(list(1), dim=c(1,1))) # matrix class(structure(list(1), dim=1, class='foo')) # foo 

最后,类可以返回多个string,但只有类属性是这样的。 第一个string的值是主类的类,下面是它inheritance的东西。 组成课程总是长1。

 # Here "A" inherits from "B", which inherits from "C" class(structure(1, class=LETTERS[1:3])) # "A" "B" "C" # an ordered factor: class(ordered(3:1)) # "ordered" "factor" 

R中的所有东西都有(正好一个)类吗?

确实有一个是绝对不正确的:

 > x <- 3 > class(x) <- c("hi","low") > class(x) [1] "hi" "low" 

一切都有(至less一个)课。

R中的所有东西都有(恰好一种)模式吗?

不确定,但我怀疑是这样。

如果有的话,“typeof”告诉我们什么?

typeof给出了一个对象的内部types。 根据?typeof可能值是:

vectortypes“逻辑”,“整数”,“双”,“复杂”,“字符”,“原始”和“列表”,“NULL”,“封闭”(function),“特殊”和“内build”(基本function和操作符),“环境”,“S4”(一些S4对象)和其他在用户级别不可见的符号(“符号”,“pairist”,“promise”,“language”,“char” “…”,“any”,“expression”,“externalptr”,“bytecode”和“weakref”)。

mode依赖于typeof。 从?mode

除了types“integer”和“double”被返回为“numeric”之外,模式与types具有相同的一组名称(请参阅typeof)。 types“特殊”和“内build”作为“function”返回。 键入“符号”称为模式“名称”。 types“language”返回为“(”或“call”。

还需要其他什么信息来完整描述实体? (例如,“列表”存储在哪里?)

一个列表有class级列表:

 > y <- list(3) > class(y) [1] "list" 

你的意思是vector化吗? length应该足以满足大多数目的:

 > z <- 3 > class(z) [1] "numeric" > length(z) [1] 1 

3想象成长度为1的数字向量,而不是一些原始的数字types。

结论

你可以很好的与classlength 。 当你需要其他的东西的时候,你可能不需要问他们为什么:-)

下面是一些代码,用于确定四种types的函数, class , mode , typeof和storage.mode为每种R对象返回的内容。

 library(methods) library(dplyr) library(xml2) setClass("dummy", representation(x="numeric", y="numeric")) types <- list( "logical vector" = logical(), "integer vector" = integer(), "numeric vector" = numeric(), "complex vector" = complex(), "character vector" = character(), "raw vector" = raw(), factor = factor(), "logical matrix" = matrix(logical()), "numeric matrix" = matrix(numeric()), "logical array" = array(logical(8), c(2, 2, 2)), "numeric array" = array(numeric(8), c(2, 2, 2)), list = list(), pairlist = .Options, "data frame" = data.frame(), "closure function" = identity, "primitive function" = `+`, "special function" = `if`, environment = new.env(), null = NULL, formula = y ~ x, expression = expression(), call = call("identity"), name = as.name("x"), "paren in expression" = expression((1))[[1]], "brace in expression" = expression({1})[[1]], "S3 lm object" = lm(dist ~ speed, cars), "S4 dummy object" = new("dummy", x = 1:10, y = rnorm(10)), "external pointer" = read_xml("<foo><bar /></foo>")$node ) type_info <- Map( function(x, nm) { data_frame( "spoken type" = nm, class = class(x), mode = mode(x), typeof = typeof(x), storage.mode = storage.mode(x) ) }, types, names(types) ) %>% bind_rows knitr::kable(type_info) 

这是输出:

 |spoken type |class |mode |typeof |storage.mode | |:-------------------|:-----------|:-----------|:-----------|:------------| |logical vector |logical |logical |logical |logical | |integer vector |integer |numeric |integer |integer | |numeric vector |numeric |numeric |double |double | |complex vector |complex |complex |complex |complex | |character vector |character |character |character |character | |raw vector |raw |raw |raw |raw | |factor |factor |numeric |integer |integer | |logical matrix |matrix |logical |logical |logical | |numeric matrix |matrix |numeric |double |double | |logical array |array |logical |logical |logical | |numeric array |array |numeric |double |double | |list |list |list |list |list | |pairlist |pairlist |pairlist |pairlist |pairlist | |data frame |data.frame |list |list |list | |closure function |function |function |closure |function | |primitive function |function |function |builtin |function | |special function |function |function |special |function | |environment |environment |environment |environment |environment | |null |NULL |NULL |NULL |NULL | |formula |formula |call |language |language | |expression |expression |expression |expression |expression | |call |call |call |language |language | |name |name |name |symbol |symbol | |paren in expression |( |( |language |language | |brace in expression |{ |call |language |language | |S3 lm object |lm |list |list |list | |S4 dummy object |dummy |S4 |S4 |S4 | |external pointer |externalptr |externalptr |externalptr |externalptr | 

在R语言定义手册中讨论R中可用对象的types。 有几种types在这里没有提到:你不能testing“promise”,“…”和“ANY”types的对象,而“字节码”和“weakref”只能在C级上使用。

这里 R源的可用types表。

添加到您的一个子问题中:

  • 还需要其他什么信息来完整描述实体?

除了classmodetypeofattributesstr等, is()也值得注意。

 is(1) [1] "numeric" "vector" 

虽然有用,但也不尽人意。 在这个例子中, 1不止于此; 它也是primefaces,有限,和一个双。 下面的函数应该显示所有的对象是根据所有可用is.(...)函数:

 what.is <- function(x, show.all=FALSE) { # set the warn option to -1 to temporarily ignore warnings op <- options("warn") options(warn = -1) on.exit(options(op)) list.fun <- grep(methods(is), pattern = "<-", invert = TRUE, value = TRUE) result <- data.frame(test=character(), value=character(), warning=character(), stringsAsFactors = FALSE) # loop over all "is.(...)" functions and store the results for(fun in list.fun) { res <- try(eval(call(fun,x)),silent=TRUE) if(class(res)=="try-error") { next() # ignore tests that yield an error } else if (length(res)>1) { warn <- "*Applies only to the first element of the provided object" value <- paste(res,"*",sep="") } else { warn <- "" value <- res } result[nrow(result)+1,] <- list(fun, value, warn) } # sort the results result <- result[order(result$value,decreasing = TRUE),] rownames(result) <- NULL if(show.all) return(result) else return(result[which(result$value=="TRUE"),]) } 

所以现在我们得到一个更完整的图像:

 > what.is(1) test value warning 1 is.atomic TRUE 2 is.double TRUE 3 is.finite TRUE 4 is.numeric TRUE 5 is.vector TRUE > what.is(CO2) test value warning 1 is.data.frame TRUE 2 is.list TRUE 3 is.object TRUE 4 is.recursive TRUE 

您还可以通过参数show.all=TRUE获得更多信息。 因为结果超过50行,所以我没有在这里粘贴任何示例。

最后,这意味着作为信息的补充来源,而不是取代之前提到的任何其他function。