Aar*_*aid 43 r language-lawyer r-faq
语言R让我困惑.实体具有模式和类,但即使这不足以完全描述实体.
这个答案说
在R中,每个"对象"都有一个模式和一个类.
所以我做了这些实验:
> class(3)
[1] "numeric"
> mode(3)
[1] "numeric"
> typeof(3)
[1] "double"
Run Code Online (Sandbox Code Playgroud)
到目前为止公平,但后来我传入了一个向量:
> mode(c(1,2))
[1] "numeric"
> class(c(1,2))
[1] "numeric"
> typeof(c(1,2))
[1] "double"
Run Code Online (Sandbox Code Playgroud)
这没有意义.当然,整数向量应该具有与单个整数不同的类或不同的模式吗?我的问题是:
更新:显然,文字3只是长度为1的向量.没有标量.好吧但是......我试过mode("string")了"character",让我觉得字符串是一个字符向量.但如果这是真的,那么这应该是真的,但事实并非如此!c('h','i') == "hi"
Tom*_*mmy 53
我同意R中的类型系统相当奇怪.这种方式的原因是它已经发展了很长一段时间......
请注意,您错过了一个类似类型的函数storage.mode,还有一个类类函数,oldClass.
所以,mode并且storage.mode是旧式的(storage.mode更准确的地方),并且typeof是更新,更准确的版本.
mode(3L) # numeric
storage.mode(3L) # integer
storage.mode(`identical`) # function
storage.mode(`if`) # function
typeof(`identical`) # closure
typeof(`if`) # special
Run Code Online (Sandbox Code Playgroud)
然后class是一个完全不同的故事.class主要class是对象的属性(这正是oldClass返回的属性).但是,当未设置class属性时,该class函数将根据对象类型和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
Run Code Online (Sandbox Code Playgroud)
最后,该类可以返回多个字符串,但前提是class属性是这样的.第一个字符串值,然后种主类,以及随后的是它从继承.组成的类总是长度为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"
Run Code Online (Sandbox Code Playgroud)
Ric*_*ton 17
下面是一些代码,用于确定每种R对象的四种类型函数,类,模式,typeof和storage.mode返回值.
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,
"builtin 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)
Run Code Online (Sandbox Code Playgroud)
这是输出:
|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 |
|builtin 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 |
Run Code Online (Sandbox Code Playgroud)
R语言定义手册中讨论了R中可用的对象类型.这里没有提到的几种类型:您无法测试"promise","..."和"ANY"类型的对象,"bytecode"和"weakref"仅在C级可用.
R源中可用类型的表格在这里.
Dom*_*ois 13
添加到您的一个子问题:
- 完整描述实体还需要哪些其他信息?
此外class,mode,typeof,attributes,str,等,is()也是值得注意的.
is(1)
[1] "numeric" "vector"
Run Code Online (Sandbox Code Playgroud)
虽然有用,但也不令人满意.在这个例子中,1不仅仅是那个; 它也是原子的,有限的和双重的.以下函数应根据所有可用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"),])
}
Run Code Online (Sandbox Code Playgroud)
所以现在我们得到一个更完整的图片:
> 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
Run Code Online (Sandbox Code Playgroud)
您还可以获得有关参数的更多信息show.all=TRUE.我没有在这里粘贴任何例子,因为结果超过50行.
最后,这是一个补充信息来源,而不是取代之前提到的任何其他功能.
编辑
要包含更多"is"函数,根据@ Erdogan的注释,您可以将此位添加到函数中:
# right after
# list.fun <- grep(methods(is), pattern = "<-", invert = TRUE, value = TRUE)
list.fun.2 <- character()
packs <- c('base', 'utils', 'methods') # include more packages if needed
for (pkg in packs) {
library(pkg, character.only = TRUE)
objects <- grep("^is.+\\w$", ls(envir = as.environment(paste('package', pkg, sep = ':'))),
value = TRUE)
objects <- grep("<-", objects, invert = TRUE, value = TRUE)
if (length(objects) > 0)
list.fun.2 <- append(list.fun.2, objects[sapply(objects, function(x) class(eval(parse(text = x))) == "function")])
}
list.fun <- union(list.fun.1, list.fun.2)
# ...and continue with the rest
result <- data.frame(test=character(), value=character(),
warning=character(), stringsAsFactors = FALSE)
# and so on...
Run Code Online (Sandbox Code Playgroud)
Ari*_*man 12
R中的所有内容都有(只有一个)类吗?
肯定是一个绝对不对:
> x <- 3
> class(x) <- c("hi","low")
> class(x)
[1] "hi" "low"
Run Code Online (Sandbox Code Playgroud)
一切都有(至少一个)课程.
R中的所有内容都有(只有一种)模式吗?
不确定,但我怀疑.
什么,如果有的话,'typeof'告诉我们什么?
typeof给出对象的内部类型.根据的可能值?typeof是:
向量类型"逻辑","整数","双","复杂","字符","原始"和"列表","空白","封闭"(功能),"特殊"和"内置"(基本功能和操作员),"环境","S4"(一些S4对象)和其他不太可能在用户级别看到的("符号","pairlist","promise","language","char", "...","any","expression","externalptr","bytecode"和"weakref").
mode依赖于typeof.来自?mode:
模式与类型具有相同的名称集(请参阅typeof),但"integer"和"double"类型返回为"numeric".类型"特殊"和"内置"作为"功能"返回.类型"符号"称为模式"名称".类型"语言"返回为"("或"呼叫".
完整描述实体还需要哪些其他信息?(例如,'listness'存储在哪里?)
列表包含班级列表:
> y <- list(3)
> class(y)
[1] "list"
Run Code Online (Sandbox Code Playgroud)
你的意思是矢量化吗? length应该足以满足大多数目的:
> z <- 3
> class(z)
[1] "numeric"
> length(z)
[1] 1
Run Code Online (Sandbox Code Playgroud)
可以将其3视为长度为1的数字向量,而不是某些原始数字类型.
结论
你可以用class和完成length.当你需要其他东西的时候,你可能不必问他们的用途:-)