Reputation: 1947
I want to write a very simple function. If I put vector in output I should get 'A', if matrix 'B' and if list 'C'. I wrote :
check<-function(x){
if (is.numeric(x)){'A'}
else if (is.matrix(x)){'B'}
else if (is.list(x)){'C'}
}
And it's wrong function because :
Mat<-rnorm(rnorm(4),2,2)
check(Mat)
'A'
The reason is clear when we use code :
is.numeric(Mat)
But me question is : how can I change my function to work properly ? I do not have idea how can I do it
Upvotes: 0
Views: 59
Reputation: 6206
There are 2 problems. Firstly, you have passed to your function a 1 dimensional vector, not a matrix:
Mat = rnorm(rnorm(4),2,2)
> is.vector(Mat)
[1] TRUE
A matrix in R is a 2 dimensional vector:
Secondly, something can both be a numeric type and a matrix object:
Mat = as.matrix(rnorm(9), nrow=3)
> is.numeric(Mat)
[1] TRUE
> is.numeric(Mat)
[1] TRUE
If you want to check whether you have a list, vector or matrix, you should change your function:
check = function(x){
if (is.atomic(x) & !is.matrix(x)){'A'}
else if (is.matrix(x)){'B'}
else if (is.list(x)){'C'}
}
> a = rnorm(9)
> check(a)
[1] "A"
> a = matrix(rnorm(9), nrow=3)
> check(a)
[1] "B"
> a = list(rnorm(9))
> check(a)
[1] "C"
Upvotes: 0
Reputation: 1300
Try with inherits
:
check<-function(x){
if (inherits(x, 'numeric')){'A'}
else if (inherits(x, 'matrix')){'B'}
else if (inherits(x, 'list')){'C'}
}
check(numeric(1)) # "A"
check(matrix(1)) # "B"
check(list(1)) # "C"
# Using something else (e.g. data.frame) returns null
(check(data.frame(1))) # NULL
Upvotes: 1