itthrill
itthrill

Reputation: 1376

operations inside vectorised functions in R

I have a dummy non vector function that takes two arguments as inputs. I have a similar(not exactly identical) vector function that works on list of arguments.

However in the non vector function I can also do some operations on the argument itself(please refer to lines with comments). I am trying to figure out a way to do the same in the vector form of the functions as well.

nonvectorfunction<-function(x,i){

  if (i==1){
    x<-x^0.5 # not implemented in vectorfunction
    if (x==10){
      x<-x+1
    } else {
      x<-x-1
    }
  }

  if (i==2){

    x<-x^(1/3) # not implemented in vectorfunction
    if (x==10){
      x<-x-1
    } else {
      x<-x+1
    }
  }
  return(x)
}


vectorfunction <- function(x,i) {

  x <- case_when(
    i==1 ~ case_when(
      x==10 ~ x+1,
      TRUE ~ x-1),
    i==2 ~ case_when (
      x==10 ~ x-1,
      TRUE ~ x+1
    ))

  return(x)
}



sample.list<-c(10,9,8,10)

nonvectorfunction(sample.list[1],1)
nonvectorfunction(sample.list[3],2)
nonvectorfunction(sample.list,1)


vectorfunction(sample.list,1)

Output:

> nonvectorfunction(sample.list[1],1)
[1] 2.162278
> nonvectorfunction(sample.list[3],2)
[1] 3
> nonvectorfunction(sample.list,1)
[1] 2.162278 2.000000 1.828427 2.162278
Warning message:
In if (x == 10) { :
  the condition has length > 1 and only the first element will be used
#this is expected because I am passing a list to non vector function
> 
> vectorfunction(sample.list,1)
[1] 11  8  7 11

as seen above vectorised functions handles the list well.

Upvotes: 3

Views: 48

Answers (1)

akrun
akrun

Reputation: 887881

As i takes only a single value, it can be either used with if/else or with switch

vectorfunction <- function(x,i) {
   switch(i, 
   `1` = {
        x <- x^0.5
        case_when(x == 10 ~ x + 1, TRUE ~ x - 1)
   },
   `2` = {
        x <- x^(1/3)
      case_when( x== 10 ~ x -1, TRUE ~ x +1)


   },
   default = x


   )


  }

vectorfunction(sample.list,1)
#[1] 2.162278 2.000000 1.828427 2.162278
vectorfunction(sample.list,2)
#[1] 3.154435 3.080084 3.000000 3.154435

Comparing with nonvectorfunction

sapply(sample.list, nonvectorfunction, i = 1)
#[1] 2.162278 2.000000 1.828427 2.162278
sapply(sample.list, nonvectorfunction, i = 2)
#[1] 3.154435 3.080084 3.000000 3.154435

Or the nonvectorfunction can be Vectorized

Vectorize(nonvectorfunction)(sample.list, i = 1)
#[1] 2.162278 2.000000 1.828427 2.162278

Upvotes: 1

Related Questions