parSapplyLB with missing arguments

66 Views Asked by At

Suppose fun is a function with 3 arguments (x, y, z) and y or z needs to be specified, but not both.

fun <- function(x, y, z) {
  if (missing(y)) {
    x^2
  } else {
    x^5
  }
} 

Now assume this function gets call within another function as:

fun.v1 <- function(x, y, z) {
  sapply(x, fun, y, z)
}

> fun.v1(1:5, y = 4)
[1]  1   32  243 1024 3125
> fun.v1(1:5, z = 4)
[1]  1  4  9 16 25

Rather than using sapply, now I want to implement a parallel backend:

require(parallel)
fun.v2 <- function(x, y, z) {
  cl <- makeCluster(2)
  bf <- parSapplyLB(cl = cl, X = x, fun, y, z)
  stopCluster(cl = cl)
}

fun.v2(1:5, y = 4)
fun.v2(1:5, z = 4)

This code gives an error. Is there a way to fix this?

Update: Below code works as intended. But is there a neater way of doing this?

fun <- function(x, y, z) {
  if (is.null(y)) {
    x^2
  } else {
    x^5
  }
}

fun.v2 <- function(x, y, z) {
  cl <- makeCluster(2)
  tmp1 <- if(missing(y))
    NULL
  else y
  tmp2 <- if(missing(z))
    NULL
  else z
  bf <- parSapplyLB(cl = cl, X = x, fun, y = tmp1, z = tmp2)
  stopCluster(cl = cl)
  return(bf)
}


> fun.v2(1:5, y = 4)
[1]  1   32  243 1024 3125
> fun.v2(1:5, z = 4)
[1]  1  4  9 16 25
1

There are 1 best solutions below

1
M. Papenberg On

It seems that y and z are both non-optional arguments. You can make them optional as follows:

fun.v2 <- function(x, y = NULL, z = NULL) {
  cl <- makeCluster(2)
  bf <- parSapplyLB(cl = cl, X = x, fun, y, z)
  stopCluster(cl = cl)
}

This no longer throws an error.