Create a generalized function in R

Viewed 59


a<-c(0,1,1,0)
b<-c(1,0,0,0)
c<-c(0,0,0,1)

binary_subset<-function(a){
  a_seq = lapply(a, seq, 0)   # keep 0s as 0, make 1s c(1, 0)
  subset=do.call(expand.grid, a_seq)
  colnames(subset)=(1:length(a))
  return(subset)
}

test_fun<-function(a,b,c,d){
list <- list(a,b,c,d)

interactions_abc<-do.call("rbind",lapply(list, binary_subset))

interactions_no_duplicate<-unique(interactions_abc[1:length(a)])
rownames(interactions_no_duplicate)=1:nrow(interactions_no_duplicate)

interactions_no_duplicate
}
>test_fun(a,b,c,d)
   Error in test_fun(a, b, c, d) : object 'd' not found

I am trying to write a function where the input is not fixed. I have defined the function for 4 binary vectors. If I input 3 binary vectors, I am getting an error because the 4th vector is missing. This will work only if I input 4 binary vectors.

How can I fix this? Means: if I input 2 or 3 vectors, the function will produce the corresponding output; that means the function will run for two vectors and ignore the rest.

2 Answers

Maybe you can use ... for the function arguments, e.g.,

test_fun <- function(...) {
  list <- list(...)
  interactions_abc <- do.call("rbind", lapply(list, binary_subset))

  interactions_no_duplicate <- unique(interactions_abc[1:length(list[[1]])])
  rownames(interactions_no_duplicate) <- 1:nrow(interactions_no_duplicate)

  interactions_no_duplicate
}

Consider passing in a list as single, sole argument by retrieving all numeric vectors from global environment with eapply and Filter. Below functions are re-factored for one line where { and } are optional.

a <- c(0,1,1,0)
b <- c(1,0,0,0)
c <- c(0,0,0,1)

binary_subset <- function(x) {
    setNames(do.call(expand.grid, lapply(x, seq, 0)), 1:length(a))
}

test_fun <- function(mylist) {
    data.frame(unique(do.call("rbind", lapply(mylist, binary_subset))),
               row.names = NULL, check.names = FALSE)    
}

vecs <- Filter(is.numeric, eapply(.GlobalEnv, identity))

test_fun(vecs)

Online Demo

Related