F.Alanazi F.Alanazi - 9 months ago 26
R Question

How to call a function using *apply with different data, where output is list and intput is list of 2x2 matrix?

I have data from 10 runs of a simulation, stored as a list. I want to call a function

FUN1
with this data, without repeating the code 10 times. The output from
FUN1
is a value of model parameter such that:

$theta=5
$Theta= 0.5
$pi_1 = 0.6
$pi_2 = 0.4
$loglik_1 = 123.6
$loglik_2 = 23.56


So, this how the output of
FUN1
when I fit it to one of the 10 runs. I would like to have the output of all runs without refit my function for each run.

I know that we can use loop-family functions in R such as
lapply
(list) or
tapply
(vector) functions. I tried both of them but both did not work.

Here is my data:

library(VineCopula)
library(copula)
Runs = 10
Saveas = vector(mode = "list", length = Runs)
pb <- txtProgressBar(min = 0, max = Runs, style = 3)

for(j in 1:Runs) {
setTxtProgressBar(pb, j)
N=2000
dim = dim
U = runif(N, min=0,max=1)
X = matrix(NA, nrow=N, ncol=2)

inds <- U < 0.7

X[inds, ] <- rCopula(sum(inds),
claytonCopula(1, dim=2))

X[!inds, ] <- rCopula(N - sum(inds),
frankCopula(4, dim=2))
Saveas[[j]] = X
}


This is my function:

FUN1 <- EM_mixture_copula(data =
Saveas[[j]],pi_1=pi_1,pi_2=pi_2,theta = theta,
Theta=Theta, tol = .00001, maxit = 1000)


Here is my tries with the errors that I got:

> result <- tapply(X,FUN1,simplify = T)
Error in tapply(X, FUN, simplify = T) : arguments must have same length.

> Result <– lapply(X,FUN1)
Error in get(as.character(FUN), mode = "function", envir = envir) : object 'F' of mode 'function' was not found.


Note that the output of copula is a matrix(nrow=N, ncol=2) (since the dimension of copula is 2). For example:

xx <-

rCopula(N=4 ,claytonCopula(0.5))
xx
[,1] [,2]
[1,] 0.6269311043 0.229429156
[2,] 0.3257583519 0.268244546
[3,] 0.7446442267 0.436335203
[4,] 0.3186246504 0.163209827


Where 0.5 is copula parameter.

Any help, please?

Answer Source

I guess dim inside sim_fun should be 1. Since, I do not have data or the libraries installed, this answer is an unverified post. However, it will help you figure out the solution from here.

sim_fun <- function( N )
{
  U=runif(N, min=0,max=1)
  inds <- U < 0.7
  X <- matrix(NA, nrow = N, ncol = 2)
  X[inds, 1:2] <- rCopula(sum(inds), claytonCopula(1, dim=2))
  X[!inds, 1:2] <- rCopula(N - sum(inds), frankCopula(4,dim=2))
  return( X )
}

set.seed(1L)  # set state of random number generator
sim_data <- replicate( n = 10, sim_fun( N = 2000 ))  # get simulated data 10 times

# apply EM function on the simulated data
apply( sim_data, 3, function( x ) EM_mixture_copula(data =  x,
                                                    pi_1 = pi_1,
                                                    pi_2=pi_2,
                                                    theta = theta, 
                                                    Theta=Theta, 
                                                    tol = .00001,
                                                    maxit = 1000))