user7905871
user7905871

Reputation:

How to make a function looping based on a condition in R

My original function is so complex. There is a complex computation. So, I have a condition where my function stop if this condition is met. That is good for me to not go further for the unneeded computation. Due to this, I try to give a simple example here to make my question clear for you. The main idea of my original function is to do some computation, and if the given condition is met, then the function stop otherwise it completes for the second computation.

Hence, I write a simple function, where the loop of this function is based on a specific condition. In my function I try to do the following:

  1. Compute the first two multiplication.
  2. If the value of the second multiplication is smaller than the first one, then, I would like the function to stop and return me the result.
  3. Else, I would like my function to compute the third result. And compare it with the second one. If the third result is smaller than the second one then stop, and so on for all my element.

Here is my try:

myfun <- function(x,y){
    xy <- list()
    n <- length(x)
    for (i in 1:n){
        xy[[1]] <- x[[1]]*y[[1]]
        xy[[2]] <- x[[2]]*y[[2]]
        if(xy[[2]] < xy[[1]]){
            stop
        }else{
            xy[[i]] <- x[[i]]*y[[i]]
        }
    }
    return(xy)
}
x <- rnorm(10, 0,1)
y <- rnorm(10, 0, 1)
myres <- myfun(x, y)

The problem of my function is that the condition is only worked with the first and second element. I would like to do the 3 listed steps.

Any help, please?

Upvotes: 0

Views: 61

Answers (1)

gfgm
gfgm

Reputation: 3647

It will be slow and painful to try to write out all of these conditions. You can create the vector of products, and evaluate whether its difference is positive and negative in one go, and then return the product if the condition holds (as suggested in comments):

func <- function(x, y) {
  xy <- x*y
  d.xy <- diff(xy)
  if (all(d.xy > 0)) {
    xy
  } else {
    cat("Product", which(d.xy < 0)[1]+1, "is greater than product", 
                   which(d.xy < 0)[1])
  }
}

set.seed(8)
x <- rnorm(10, 0,1)
y <- rnorm(10, 0, 1)

func(x, y)
#> Product 3 is greater than product 2

x <- 1:10
y <- 2:11
func(x, y)
#>  [1]   2   6  12  20  30  42  56  72  90 110

Additions due to question edits

OK in light of your edits to your question, here is a version that assumes that the cost of computing the function of x and y is very time consuming:

## assuming time to compute vector of results is v. v. high
func2 <- function(x, y) {
  cval <- x[1] * y[1]
  res <- cval
  for (i in 2:length(x)) {
    res[i] <- x[i] * y[i]
    if (res[i] < cval) {
      break
    }
    cval <- res[i]
  }
  res
}

set.seed(8)
x <- rnorm(10, 0,1)
y <- rnorm(10, 0, 1)

func2(x, y)
#> [1]  0.06426797  0.24543874 -0.19531099

x <- 1:10
y <- 2:11
func2(x, y)
#>  [1]   2   6  12  20  30  42  56  72  90 110

In this version of the function I return the values of the result that are computed (rather than returning nothing), as if it takes a long time to compute them might be better to hang on to them in case they prove useful.

Upvotes: 2

Related Questions