Home > Enterprise >  Error in passing a constant argument to mapply() function
Error in passing a constant argument to mapply() function

Time:02-07

I have created a function that run FastICA on a dataset with different number of components and it returns ICA signals (S matrix) but in a long format.

compute_ICA <- function(r)
  
{
   res_ICA <- fastICA(df, r, alg.typ = "parallel", fun = "logcosh", alpha = 1,
             method = "R", row.norm = FALSE, maxit = 200,
             tol = 0.0000001, verbose = FALSE)
   df_long<-reshape2::melt(as.data.frame(res_ICA$S))
   return(df_long)
}

Now I want to repeat this function 100 times for one specific r (number of components) and keep track of the iteration number. So I tried this :

iterate_ICA <- function(r,t)
{for (i in r)
{
  res<-mapply(compute_ICA, t, SIMPLIFY = FALSE)
  res_unzip<-do.call(rbind, res)
  res_unzip$iteration <- i
  return(res_unzip)
}
  }

But when I try applying the iterate_ICA() function like this I get this error:

res_zip<-mapply(iterate_ICA, 1:100, 3, SIMPLIFY = FALSE)
Error in dots[[1L]][[1L]] : object of type 'closure' is not subsettable

Does anyone know what's wrong with this function?

Thanks in advance!

CodePudding user response:

I cannot reproduce the error, however, I think you misunderstood what mapply does.

When you apply mapply to a function FUN, with arguments that are lists or vectors (consider that R basic types like numbers or characters are always vectors), the function FUN is called iteratively on the first element of all the arguments, then on the second, etc. Arguments are recycled if necessary.

For instance:

fn <- function(num, let) {
  data.frame(num = num, let = let)
}

mapply(FUN = fn, 1:5, letters[1:5], SIMPLIFY = FALSE)

##> [[1]]
##>   num let
##> 1   1   a
##> 
##> [[2]]
##>   num let
##> 1   2   b
##> 
##> [[3]]
##>   num let
##> 1   3   c
##> 
##> [[4]]
##>   num let
##> 1   4   d
##> 
##> [[5]]
##>   num let
##> 1   5   e

To comply with the expected behavior you described, the iterate_ICA function should read like this:

iterate_ICA<-function(r,t) {
  res <-  compute_ICA(t)
  return(cbind(res, iteration = r))
}

Then you iterate it using mapply:

res <- mapply(iterate_ICA, 1:100, 3, SIMPLIFY = FALSE)

Finally, you merge all the replicates:

res_unzip <- do.call(rbind, res)
  •  Tags:  
  • Related