sbeleidy
sbeleidy

Reputation: 371

How to setup a recursive lapply for specific values ex.w[i] == n[i]?

Background

I'm developing a function that takes in a value for w between 1 and 3 and returns n values from one of 3 distributions. The problem I am having is when n or w are not of length 1. So I've added 2 parameters nIsList and wIsList to create the functionality I want. The way I want this to work is as follows:

(Works as needed)

If nIsList ex( c(1,2,3) ) return a list equivalent to running consume(w,1), consume(w,2), consume(w,3)

(Works as needed)

If wIsList ex( c(1,2,3) ) return a list equivalent to running consume(1,n), consume(2,n), consume(3,n)

(Doesn't work as needed)

If nIsList ex(1,2,3) and wIsList ex(1,2,3) return a list equivalent to running consume(1,1), consume(2,2), consume(3,3). Instead, I get a list equivalent to running [consume(1,1), consume(1,2), consume(1,3)], [consume(2,1), consume(2,2), consume(2,3)], [consume(3,1),consume(3,2), consume(3,3)]

I understand why I am getting the results I am getting. I just can't seem to figure out how to get the result I want. (As explained above)

Question

I want the function to provide a list for each element in w and n that is consume(w[i], n[i]) when wIsList & nIsList are True. Is there a way to do that using lapply?

The code:

library("triangle")
consume <- function(w, n=1, nIsList=F, wIsList=F){
  if(!nIsList & !wIsList){  
    if(w==1){
      return(rtriangle(n,0.3,0.8))
    }else if(w==2){
      return(rtriangle(n,0.7,1))
    }else if(w==3){
      return(rtriangle(n,0.9,2,1.3))
    }
  }
  else if(nIsList & !wIsList){
    return(sapply(n, consume, w=w))
  }
  else if(nIsList & wIsList){
    return(lapply(n, consume, w=w, wIsList=T))
  }
  else if(!nIsList & wIsList){
    return(lapply(w, consume, n))
  }
}

Note: I am having trouble summarizing this question. If you have any suggestions for renaming it please let me know and I will do so.

Upvotes: 0

Views: 65

Answers (1)

sbeleidy
sbeleidy

Reputation: 371

Thanks to JPC's comment, using mapply does the trick. The new code is as follows:

consume <- function(w, n=1){
  nIsList <- length(n) > 1 # Change based on JPC's second comment
  wIsList <- length(w) > 1 # Change based on JPC's second comment
  if(!nIsList & !wIsList){  
    if(w==1){
      return(rtriangle(n,0.3,0.8))
    }else if(w==2){
      return(rtriangle(n,0.7,1))
    }else if(w==3){
      return(rtriangle(n,0.9,2,1.3))
    }
  }
  else if(nIsList & !wIsList){
    return(sapply(n, consume, w=w))
  }
  else if(nIsList & wIsList){
    return(mapply(consume,w,n)) ## Updated portion
  }
  else if(!nIsList & wIsList){
    return(lapply(w, consume, n)) 
  }
}

Upvotes: 0

Related Questions