crsh / papaja

papaja (Preparing APA Journal Articles) is an R package that provides document formats to produce complete APA manuscripts from RMarkdown-files (PDF and Word documents) and helper functions that facilitate reporting statistics, tables, and plots.
https://frederikaust.com/papaja_man/
Other
652 stars 132 forks source link

Formatting correlation tables from psych::corr.test() #210

Open lgluca opened 6 years ago

lgluca commented 6 years ago

Hi there! I have been using papaja for a while now and i find it terrific! Thanks for all the work, and saving hours of my time! (If you want some bavarian beer, just PM an address:)

And now to my issue: i have been trying to create a function that creates a correlation half-matrix, takes the M and SDs of the variables involved and put it all together in an APA format. I think it is a good function (and you can have it and implement it if you think its worthy), but you can see from the test below with the apa_table() function, i am not able to delete the leading zeroes, nor to align the to decimals as the APA format requires. I have found nothing of the sort in papaja... A big thank you,

Georg

glrstab<- function(x, export=FALSE) {

  r <-corr.test(x)$r    #taking just the correlation matrix; no N, or p
  p <-corr.test(x)$p    #taking the p*s

 #define notions for significance levels
  mystars <- ifelse(p < .001, "**"
                    , ifelse(p < .01, "**"
                             , ifelse(p < .05, "*"
                                      , ifelse(p < .10, "+", " "))))

  #round r, define new matrix Rnew with the correlations from rnd and paste mystars
  rnd  <- papaja::printnum(r, gt1 = FALSE, digits = 2)  #round, drop leading 0 - Thanks CRSH!                                                    
  Rnew <- matrix(paste(rnd, mystars, sep=""), ncol=ncol(rnd)) 

   #remove 1.0 correlations from diagonal  and set the strings
  diag(Rnew) <- ''      
  Rnew[upper.tri(Rnew)] <- ''                                                   

  rownames(Rnew) <- paste(1:ncol(rnd), colnames(rnd), sep=" ")         #define number and name
  colnames(Rnew) <- paste(1:ncol(rnd), "", sep="")                 #define number

 #fun-part: we trim the top half 
  Rnew[upper.tri(Rnew)] <- ''           
  Rnew

  Rnew <- cbind(round(describe(x)[,3:4],2), Rnew)            #describe x, M sD - put them in the matrix
  colnames(Rnew)[1:2] <- c("M","SD")                                #Beschriftung der neuen Spalten
  Rnew <- Rnew[,1:(ncol(Rnew)-1)]                                       #delete the last column (ugly)

  #export to clipboard

    if (export==TRUE){
    result<-write.table(Rnew
                        , "clipboard"
                        , sep=";"
                        , row.names=FALSE)
  }
  else result <- Rnew
  return(result)

}

tests and example


library(psych)
library(papaja)

bigfive    <-epi.bfi[,1:5]
a             <-glrstab(bigfive) #the function in action!

rownames(a)   <- c("A", "B", "C", "D", "E")
colnames(a)   <- c("$M$", "$SD$", "1", "2", "3", "4")
apa_table(a
                , escape  = FALSE
                , caption = "Correlation matrix of the main variables"
                , note    = "Very fine!")
crsh commented 6 years ago

Hi Georg, thanks for the kind words. 🍻😋

Also, thanks you for sharing your function. I imagine this could be helpful for other users, too. Given that psych::corr.test() returns a proper S3 object, it should be straight forward to to add support for these objects to apa_print(). I'll add it to the todo list, but I'm currently holding new features because we are trying to prepare the first CRAN release. So it might be a while before I can add proper support. Until then, you could simply use papaja::printnum() to format the correlations. Simply use the following line in your function:

rnd  <- printnum(r, gt1 = FALSE, digits = 2)
lgluca commented 6 years ago

wow. you just solved a problem i have been having for 48h. I'll update the function. (beer offering is still on the table, and whatever I can do to help with the package)

Zweckoptimismus commented 6 years ago

Guys, thanks for this extremely helpful function. I could offer tea from northern Germany in exchange. ;-) If you are here or in Hagen, please stop by.

However, I received an error because describe() doesn't return a data.frame and, consequently, round() had nothing to round. I changed the respective part to this:

round(data.frame(describe(x))[,3:4],2)

Thank you very much!

prasadkrec commented 6 years ago

Hi

If i make changes (i.e., i insert this (round(data.frame(describe(x))[,3:4],2)) line into the function. I get the following the error:

Error in as.data.frame.default(x[[i]], optional = TRUE, stringsAsFactors = stringsAsFactors) : cannot coerce class ‘"describe"’ to a data.frame

Any other ways I could get this function written by Georg to work?

Eager to hear

Cheers prasad

jnalice commented 5 years ago

hello, i encountered the same problem when outputted the results of corr.test(). The error looks like "Error in as.data.frame.default(x[[i]], optional = TRUE, stringsAsFactors = stringsAsFactors) : cannot coerce class "c("psych", "corr.test")" to a data.frame". How can I transfer the results into a data.frame?or how can i export the results to a .csv file? thank you for your help regards alice

crsh commented 5 years ago

I think this question would be well suited for StackOverflow. If you provide a reproducible example of the problem, I'd be happy to try to answer it over there.

hsorlie commented 4 years ago

Hi, @lgluca ! I'm writing a paper with multilevel methods using papaja, and I was looking for a function to create a correlation matrix for multilevel data with within-level and between-level correlations below/above the diagonal, respectively. I came across your function, which I thought was great! I hope you don't mind, but I copied your function and adapted it slightly to accommodate multilevel data.

@crsh : If this can be used in a future version of papaja, please feel free. My adaptations of @lgluca 's code might not be particularly elegant, but it works. Or seems to, at least.

conig commented 4 years ago

Looks like many solutions have been found here. If anyone wants a package which will do a correlation table compatible with apa_table I've got one hosted on CRAN made for this. Once papaja is up on CRAN I'll write a method to make the process easier.

#install.packages("corx")
library(corx)

x <- corx(mtcars[,1:6],
          triangle = "lower",
          stars = c(0.05, 0.01, 0.001),
          describe = c(`$M$` = mean, `$SD$` = sd))

papaja::apa_table(x$apa, # apa contains the data.frame needed for apa_table
                  caption = "Example corr matrix",
                  note = "* p < 0.05; ** p < 0.01; *** p < 0.001",
                  escape = F)

example

crsh commented 4 years ago

Looks great, thank you for sharing!