In one way, since in R,
Everything that happens is a function call (John Chambers, part 2),
call
s are the basic language objects in R.
cc <- quote( sin(x) )
cc
## sin(x)
class(cc)
## [1] "call"
Looking closely, call
s are made from symbol
s, here, sin(x)
is made from the two symbols sin
and x
:
length(cc)
## [1] 2
c1 <- cc[[1]]; c1
## sin
c2 <- cc[[2]]; c2
## x
typeof(c1)
## [1] "symbol"
str(c2)
## symbol x
Since in R,
Everything that exists is an object (John Chambers, part 1),
we want to find out what “kind” of an object we have. The most useful “user-level” function to get an idea about an object is str()
for displaying the structure of an R object… It is used very often interactively, to get both a bit of an overview and some details about object’s structure. str()
is not meant to be used as tool to be used in other functions, so from a programmeR’s view, the standard functions for object inspectionto use are class()
which is “high-level” and typeof()
which is low-level. For historical reasons (back compatibility with S / S+), another low-level inspector function is storage.mode()
and another higher-level one is mode()
.
Here, we use them on a somewhat representative collection of R objects (all conveniently put in a list
) to see how these R objects, are categorized by the different “inspection” functions.
l.ex <- list(one=1, s1= 1:2, pi=pi, I=1i, let= c("A", "a", "b", ":::"),
fn = mean, fn2 = c, fnSpec = `function`,
n = as.name("Mä"), n2 = quote(x), ex = expression(1+1),
cl = call("round",10), cl2 = quote(sin(x)), formals = formals(lm), arg1 = formals(lm)[[1]])
str(l.ex, vec.len = 16, max.level = 1)
## List of 15
## $ one : num 1
## $ s1 : int [1:2] 1 2
## $ pi : num 3.14
## $ I : cplx 0+1i
## $ let : chr [1:4] "A" "a" "b" ":::"
## $ fn :function (x, ...)
## $ fn2 :function (..., recursive = FALSE)
## $ fnSpec :.Primitive("function")
## $ n : symbol Mä
## $ n2 : symbol x
## $ ex : expression(1 + 1)
## $ cl : language round(10)
## $ cl2 : language sin(x)
## $ formals:Dotted pair list of 14
## $ arg1 : symbol
myShow <- function(x, max.length= 1000L) {
r <- tryCatch(format(x), error=function(e)e)
r <- if(inherits(r, "error"))
tryCatch(as.character(x), error=function(e)e)
else paste(r, collapse=" ")
r <- if(inherits(r, "error"))
tryCatch(capture.output(x), error=function(e)e)
else paste(r, collapse=" ")
substr(r, 1L, max.length)
}
cbind(show = sapply(l.ex, myShow, max.length = 16),
typeof = sapply(l.ex, typeof),
st.mode = sapply(l.ex, storage.mode),
mode = sapply(l.ex, mode),
class = sapply(l.ex, class)) -> tab.ex
Now instead of printing this directly - which is readable and nice already, let’s be “advanced” and use a knitr
package feature to produce “raw markdown” tables:
knitr::kable(tab.ex, format="pandoc")
show | typeof | st.mode | mode | class | |
---|---|---|---|---|---|
one | 1 | double | double | numeric | numeric |
s1 | 1 2 | integer | integer | numeric | integer |
pi | 3.141593 | double | double | numeric | numeric |
I | 0+1i | complex | complex | complex | complex |
let | A a b ::: | character | character | character | character |
fn | function (x, … | closure | function | function | function |
fn2 | .Primitive(“c”) | builtin | function | function | function |
fnSpec | .Primitive(“func | special | function | function | function |
n | Mä | symbol | symbol | name | name |
n2 | x | symbol | symbol | name | name |
ex | expression(1 + 1 | expression | expression | expression | expression |
cl | round(10) | language | language | call | call |
cl2 | sin(x) | language | language | call | call |
formals | qr TRUE FAL | pairlist | pairlist | pairlist | pairlist |
arg1 | symbol | symbol | name | name |
Note: The source of this document is MM’s /sfs/u/maechler/R/MM/MISC/type-mode-class.Rmd