I try to write a function where I can throw in a abitrary number of objects and get a list of the datatypes of that objects. This is a personal task to learn S3 Generics.
What I have done so far is:
myTypes <- function(x, ...) {
dots <- list(...)
return (as.list(apply(dots, 1, myType)))
}
myType <- function(x){
UseMethod("myType")
}
myType.numeric <- function(x){
if(is.numeric(x)) "Type: numberic"
}
myType.data.frame <- function(x){
if(is.data.frame(x)) "Type: dataframe"
}
The error occurs e.g. when I call
x <- 1
y <- 3
myTypes(x,y)
I always get the error: "Error in apply(dots, 1, myType) : dim(X) must have a positive length"
and I am not sure what is wrong. Could anyone help me here? Since I am totally new to R I maybe doing something basically wrong.
The first argument of apply
must be a matrix-like object (i.e., a matrix, array or data.frame). Otherwise you get this error:
apply(1, 1, mean)
#Error in apply(1, 1, mean) : dim(X) must have a positive length
You are passing a list to apply
, which can't work because you tell apply
to apply the function along the first dimension and a list doesn't have dimensions.
You probably want to use lapply
and not apply
:
myTypes <- function( ...) {
dots <- list(...)
lapply(dots, myType)
}
x <- 1
y <- 3
myTypes(x,y)
#[[1]]
#[1] "Type: numberic"
#
#[[2]]
#[1] "Type: numberic"
Of course, it seems more useful, to simply return the class:
myTypes <- function(...) {
dots <- list(...)
lapply(dots, class)
}
myTypes(x,y)
#[[1]]
#[1] "numeric"
#
#[[2]]
#[1] "numeric"
Btw., if you use S3 method dispatch, you don't have to test the class inside the method because a method is only dispatched if the object has the corresponding class.