John
John

Reputation: 1947

Basic problem with different types of data

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

Answers (2)

user438383
user438383

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

Liman
Liman

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

Related Questions