Reputation: 18595
I'm looking at the jazz package proposed by Romain François. Romain defines a function is_bare_vector
with the following syntax:
is_bare_vector <- function(x) {
is_vector(x) && !is.object(x) && is.null(attr(x, "class"))
}
For: x <- 1
:
attr(x, "class")
# NULL
Whereas:
class(x)
# [1] "numeric"
I want to understand why those two functions provide different answers? The help on ?attr
references ?class
?attr
Note that some attributes (namely
class
,comment
,dim
,dimnames
,names
,row.names
andtsp
) are treated specially and have restrictions on the values which can be set. (Note that this is not true of levels which should be set for factors via the levels replacement function.)
?class
Many R objects have a class attribute, a character vector giving the names of the classes from which the object inherits. (Functions
oldClass
andoldClass<-
get and set the attribute, which can also be done directly.)
Upvotes: 10
Views: 382
Reputation: 16940
You just need to read on a little further in help("class")
:
If the object does not have a class attribute, it has an implicit class, notably "matrix", "array", "function" or "numeric" or the result of typeof(x) (which is similar to mode(x))
Apparently class()
will also return the implicit class if the class attribute is NULL
; let's examine the C source code --
we see that if the class attribute is of length 0, it gets the implicit class.:
SEXP R_data_class(SEXP obj, Rboolean singleString)
{
SEXP value, klass = getAttrib(obj, R_ClassSymbol);
int n = length(klass);
if(n == 1 || (n > 0 && !singleString))
return(klass);
if(n == 0) {
SEXP dim = getAttrib(obj, R_DimSymbol);
int nd = length(dim);
if(nd > 0) {
if(nd == 2)
klass = mkChar("matrix");
else
klass = mkChar("array");
}
else {
SEXPTYPE t = TYPEOF(obj);
switch(t) {
case CLOSXP: case SPECIALSXP: case BUILTINSXP:
klass = mkChar("function");
break;
case REALSXP:
klass = mkChar("numeric");
break;
case SYMSXP:
klass = mkChar("name");
break;
case LANGSXP:
klass = lang2str(obj, t);
break;
default:
klass = type2str(t);
}
}
}
else
klass = asChar(klass);
PROTECT(klass);
value = ScalarString(klass);
UNPROTECT(1);
return value;
}
Upvotes: 8