1

Can we use apply function and BiCopselect? I am trying to avoid loop in applying BiCopselect but I have not figured it out yet. Assuming I have a dataset of 3 variables, and I want to run this function for every pair. Can anyone suggest any other way to do other than loop?

This is how I do it manually

coptest12=BiCopSelect(rankresi[,1], rankresi[,2], familyset = NA)
coptest13=BiCopSelect(rankresi[,1], rankresi[,3], familyset = NA)
coptest14=BiCopSelect(rankresi[,1], rankresi[,4], familyset = NA)
coptest15=BiCopSelect(rankresi[,1], rankresi[,5], familyset = NA)
coptest23=BiCopSelect(rankresi[,2], rankresi[,3], familyset = NA)
coptest24=BiCopSelect(rankresi[,2], rankresi[,4], familyset = NA) 
coptest25=BiCopSelect(rankresi[,2], rankresi[,5], familyset = NA) 

and so on until the last code:

    coptest45=BiCopSelect(rankresi[,4], rankresi[,5], familyset = NA) 

I just tried to use apply function, but it does not seem possible as if I used:

sapply(rankresi, BiCopSelect)

the error will be "missinig u1 and u2 for BiCopSelect"

JJRB
  • 53
  • 1
  • 6
  • Do note: the [apply functions *are* loops](https://stackoverflow.com/q/28983292/1422451) (just hidden ones). – Parfait Nov 22 '18 at 02:02
  • But they're generally faster than an explicit loop, aren't they? – iod Nov 22 '18 at 02:11
  • @Parfait - e.g., a comparison of a simple apply/loop that sums up 6 columns of 1s: `microbenchmark(appl=apply(df,2,sum),loop={for(i in 1:ncol(df)) sum(df[,i])})` `Unit: microseconds` `expr min lq mean median uq max neval` `appl 232.542 305.212 393.8426 409.941 444.9935 767.303 100` `loop 5536.978 5721.857 7032.4661 5996.505 6985.2355 72034.140 100` – iod Nov 22 '18 at 02:23
  • 1
    Increase your rows size to 50K and since `apply` casts data frame to matrix before running, a similar benchmark would be: `microbenchmark(appl=apply(df,2,sum), loop={as.matrix(df); for(i in 1:ncol(df)) sum(df[,i])})`. With df: `data.frame(replicate(5, rnorm(50000)))`, apply is slower. – Parfait Nov 22 '18 at 02:35
  • Maybe add in some code you've tried and point out what's not working – Scransom Nov 22 '18 at 03:59

1 Answers1

0

You can do something like this:

myfunc<-function(df1,...) {
  pairs<-combn(names(df1),2,simplify=FALSE)
  res<-sapply(pairs,function(x) BiCopselect(df1[,x[1]],df1[,x[2]],...))
  res
}

result<-myfunc(rankresi)

This function takes the name of the dataframe, and then passes to BiCopselect one pair of columns at a time. Other arguments can be passed to BiCopselect through the ....

Here's an alternative that doesn't require the dataframe to have column names:

myfunc<-function(df1,...) {
    pairs<-combn(c(1:ncol(df1)),2,simplify=FALSE)
    res<-sapply(pairs,function(x)  BiCopselect(df1[,x[1]],df1[,x[2]],...))
    res
  }

Finally, same solution but for combinations of rows rather than columns:

myfuncbyrow<-function(df1,...) {
  pairs<-combn(c(1:nrow(df1)),2,simplify=FALSE)
 res<-sapply(pairs,function(x) BiCopselect(df1[x[1], ],df1[x[2], ],...))
 res
 }
iod
  • 7,412
  • 2
  • 17
  • 36
  • I already have the dataframe that consists 17 variables. I struggled to apply your code to that dataframe, would you mind to give me some more hints. – JJRB Nov 27 '18 at 13:22
  • What happens when you run `myfunc(df)` with your dataframe's name for df? – iod Nov 27 '18 at 16:33
  • I used this `myfunc<-function(rankresi) { pairs<-combn(names(rankresi),2,simplify=FALSE) res1<-sapply(pairs,function(x) BiCopselect(rankresi[,x[1]],rankresi[,x[2]])) res1 }` the code works but then the result show object "res1" now found – JJRB Nov 28 '18 at 12:07
  • res1 won't exist, because it's inside the function. You need to assign the result of the function to something, e.g. `res1<-myfunc(rankresi)` – iod Nov 28 '18 at 13:29
  • Thanks a lot @iod for the reply. I ran it, but the error is ` Error in combn(names(rankresi), 2, simplify = FALSE) : n < m ` This is the code that I used : `myfunc<-function(rankresi) { pairs<-combn(names(rankresi),2,simplify=FALSE) res1<-sapply(pairs,function(x) BiCopselect(rankresi[,x[1]],rankresi[,x[2]])) res1 } result<-myfunc(rankresi)` – JJRB Nov 28 '18 at 14:42
  • can you tell me what the results are when you run `names(rankresi)`? The error is saying that the number of elements you're trying to combine is smaller than 2... – iod Nov 28 '18 at 14:58
  • I see, when i ran the names function, the result is Null. My dataframe does not have column names, and that's the reason why the code does not work...I also found out the dataframe is not presented in the way that i wanted. It has 17 rows and 870 columns while I thought it had 17 columns and 870 rows. Is there any way to convert it into the way that I wanted ? – JJRB Dec 01 '18 at 10:44
  • Yes, you can wrap it in t() (for transpose) – iod Dec 01 '18 at 11:04
  • I added a version that doesn't rely on column names to my answer, but with 870 columns the number of combination is going to be prohibitive most likely, so do transpose the df first. – iod Dec 01 '18 at 11:09
  • And now there's a version by rows as well. – iod Dec 01 '18 at 11:17
  • It is running, I am waiting...Thank you so much for your help @iod..I really really appreciated !!!! – JJRB Dec 01 '18 at 11:38
  • It works!!!!! Thank you so much! You're genius @iod and you're so so kind for helping me so much ! Much appreciated! You're super!! – JJRB Dec 01 '18 at 11:51
  • Yes I did, it does not show the vote because I have low ranking :D Do you know which way is best to select the best GARCH model for each series in the dataframe. I searched online and found the garchAuto.R file and the code for it, then I ran on my data as below: `library(fGarch) source("garchAuto.R") fit = garchAuto(pregfc1, cores=1, trace=TRUE) View(fit)`. But then, when I view `fit`, the result is Null. Would you mind to tell me where should I fix it? – JJRB Dec 01 '18 at 13:30
  • Sorry, I don't actually understand any of this stuff. I could only help with the technical aspect of R wrangling. – iod Dec 01 '18 at 14:07