1

I have a list of 9 lists, see the following code where I want to loop only three lists p, r and t for Pearson, Spearson and Kendall correlations, respectively, instead of all 9 lists. The current pseudocode is the following where the test function is corrplot(M.cor, ...), see below the complete pseudocode

for (i in p.mat.all) {
...
}

Code with mtcars test data

library("psych")
library("corrplot")   

M <- mtcars 

M.cor <- cor(M)

p.mat.all <- psych::corr.test(M.cor, method = c("pearson", "kendall", "spearman"), 
   adjust = "none", ci = F)

str(p.mat.all)

str(p.mat.all$r)

str(p.mat.all$t)

str(p.mat.all$p)

Output about the list of 9 lists

List of 9
 $ r     : num [1:11, 1:11] 1 -0.991 -0.993 -0.956 0.939 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:11] "mpg" "cyl" "disp" "hp" ...
  .. ..$ : chr [1:11] "mpg" "cyl" "disp" "hp" ...
 $ n     : num 11
 $ t     : num [1:11, 1:11] Inf -21.92 -25.4 -9.78 8.22 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:11] "mpg" "cyl" "disp" "hp" ...
  .. ..$ : chr [1:11] "mpg" "cyl" "disp" "hp" ...
 $ p     : num [1:11, 1:11] 0.00 4.04e-09 1.09e-09 4.32e-06 1.78e-05 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:11] "mpg" "cyl" "disp" "hp" ...
  .. ..$ : chr [1:11] "mpg" "cyl" "disp" "hp" ...
 $ se    : num [1:11, 1:11] 0 0.0452 0.0391 0.0978 0.1143 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:11] "mpg" "cyl" "disp" "hp" ...
  .. ..$ : chr [1:11] "mpg" "cyl" "disp" "hp" ...
 $ adjust: chr "none"
 $ sym   : logi TRUE
 $ ci    : NULL
 $ Call  : language psych::corr.test(x = M.cor, method = c("pearson", "kendall", "spearman"),      adjust = "none", ci = F)
 - attr(*, "class")= chr [1:2] "psych" "corr.test"
 num [1:11, 1:11] 1 -0.991 -0.993 -0.956 0.939 ...
 - attr(*, "dimnames")=List of 2
  ..$ : chr [1:11] "mpg" "cyl" "disp" "hp" ...
  ..$ : chr [1:11] "mpg" "cyl" "disp" "hp" ...
 num [1:11, 1:11] Inf -21.92 -25.4 -9.78 8.22 ...
 - attr(*, "dimnames")=List of 2
  ..$ : chr [1:11] "mpg" "cyl" "disp" "hp" ...
  ..$ : chr [1:11] "mpg" "cyl" "disp" "hp" ...
 num [1:11, 1:11] 0.00 4.04e-09 1.09e-09 4.32e-06 1.78e-05 ...
 - attr(*, "dimnames")=List of 2
  ..$ : chr [1:11] "mpg" "cyl" "disp" "hp" ...
  ..$ : chr [1:11] "mpg" "cyl" "disp" "hp" ...

My pseudocode about looping all three correlations with the test function corrplot, but it will not work because it goes through all 9 lists

for (i in p.mat.all) {
  p.mat <- i
  print("p.mat ===========")
  print(i)    

  alpha <- 0.05 
  corrplot( M.cor,  
          method="color", 
          type="upper", 
          addCoefasPercent = TRUE, 
          tl.col = "black",
          tl.pos = "td", 
          p.mat = p.mat, sig.level = alpha, insig = "blank", 
          order = "original"
  )
}

Expected output: loop only t, p and r lists such that they can be passed to the test function corrplot

R: 3.3.1
OS: Debian 8.5

Léo Léopold Hertz 준영
  • 134,464
  • 179
  • 445
  • 697

2 Answers2

4

Or with an *apply function:

lapply(p.mat.all[c("r","p","t")], function(x) {
  # x takes now first p.mat.all$r, then p.mat.all$p, etc
  print("p.mat ===========")
  print(x)    

  alpha <- 0.05 
  corrplot( M.cor,  
          method="color", 
          type="upper", 
          addCoefasPercent = TRUE, 
          tl.col = "black",
          tl.pos = "td", 
          p.mat = x, sig.level = alpha, insig = "blank", 
          order = "original"
  )
})
David
  • 9,216
  • 4
  • 45
  • 78
emilliman5
  • 5,816
  • 3
  • 27
  • 37
  • Is this equivalent to David's answer? - - Can you please explain your `lapply` function approach little more? - - What is the benefit of it? – Léo Léopold Hertz 준영 Nov 10 '16 at 15:20
  • It does yield the same result. The biggest reason to use the apply family is speed and code efficiency. For loops tend to be clunky and lend themselves to coder error. Applies to take a little time to get your head around though, I'm still working on that, but only because I made the mistake of starting with for loops! If you were to make it identical to the plots below add `par(mfrow=c(2,2))` before the apply. – Badger Nov 10 '16 at 15:28
  • 1
    Yes this is equivalent to @David's answer, but in a more canonical R way. In R we tend to avoid for loops, by using the *apply family of functions (which are still just for loops but in a different syntax). The benefit is more compact code and potential speed ups. In your case there is no speed benefit but in others there will be. – emilliman5 Nov 10 '16 at 15:37
1

My suggestion is to filter the list before looping, i.e.,

for (i in p.mat.all[c("t", "p", "r")]) { 
    ...
}

Output for r corrplot, t corrplot and p corrplot

enter image description here

Léo Léopold Hertz 준영
  • 134,464
  • 179
  • 445
  • 697
David
  • 9,216
  • 4
  • 45
  • 78
  • 1
    Nice graphs, thanks for editing. The processing seems correct. What you see is the three different correlations between each variable. What is exactly your goal that you try to achive? – David Nov 10 '16 at 15:21
  • Lets move this to a chat?! – David Nov 10 '16 at 15:22