Nonprofit-Open-Data-Collective / compensation-appraisal

A tool for automating compensation appraisal studies for nonprofit executives.
2 stars 1 forks source link

Organizing Graphs in Unit Testing Report HTML #3

Closed olbeck closed 1 year ago

olbeck commented 1 year ago

Currently, the file "graphs.html" that is generated by running unit-testing/run-comparisons-v03.R plots each graph individually. See unit-testing/test-results/v03-test1/graphs.html for an example.

I would like to arrange the graphs in a logical order using something like par(mfrow = c(x, y)). But when I have implemented this inside each code chuck with graphs, nothing happens. I am trying to do something like this, but I cannot seem to get it to work.

What is the best way to arrange multiple graphs on a grid for easy viewing inside an RNotebook?

lecy commented 1 year ago

par( mfrow ) works for core plot objects.

If you are using ggplot you need to use one of the grid packages:

https://ggplot2-book.org/arranging-plots.html

image

https://cran.r-project.org/web/packages/egg/vignettes/Ecosystem.html

lecy commented 1 year ago

The good news is we have successfully created a nice graphical representation of a leopard seal.

image

lecy commented 1 year ago

I used this one recently and it was pretty straight-forward.

# library( patchwork )
wrap_plots( g1, g2, g3, g4)

image

olbeck commented 1 year ago

There were multiple problems when trying to arrange the graphs.

  1. The kableExtra package interferes with gridArrange and the egg packages. You can not have both. So I just deleted the kableExtra package and will deal with tables without special formatting.

  2. GGalley::ggpairs() outputs an object of class ggmatrix. ggmatrix is not a grob class (graphical object) for reasons I do not understand. So you can not use girdArrange or egg packages to arrange a ggpairs output. To get around this, I used regular graphics::pairs() function and saved each plot as a .jpg. Then arranged the images in table in html code to output. Solution is :

    
    panel.cor <- function(x, y, digits=2, prefix="", cex.cor)
    {
    usr <- par("usr"); on.exit(par(usr))
    par(usr = c(0, 1, 0, 1))
    r <- cor(x, y, use="pairwise.complete.obs")
    txt <- format(c(r, 0.123456789), digits=digits)[1]
    txt <- paste(prefix, txt, sep="")
    if(missing(cex.cor)) cex <- 0.8/strwidth(txt)
    
    test <- cor.test(x,y)
    # borrowed from printCoefmat
    Signif <- symnum(test$p.value, corr = FALSE, na = FALSE,
                  cutpoints = c(0, 0.001, 0.01, 0.05, 0.1, 1),
                  symbols = c("***", "**", "*", ".", " "))
    
    text(0.5, 0.5, txt, cex = 2 )
    text(.7, .8, Signif, cex=3, col=2)
    }
    panel.smooth <- function (x, y, col = par("col"), bg = NA, pch = par("pch"), 
    cex = 1, col.smooth = "red", span = 2/3, iter = 3, ...) 
    {
    points(x, y, pch = 19, col = gray(0.5,0.5), 
         bg = bg, cex = 1.7)
    ok <- is.finite(x) & is.finite(y)
    if (any(ok)) 
    lines(stats::lowess(x[ok], y[ok], f = span, iter = iter), 
      col = col.smooth, lwd=2, ...)
    }

make image dir

image.dir <- paste0(current.dir, "/unit-testing/test-results/", folder.name, "/images") dir.create(file.path(image.dir))

make cor plots

for(i in 1:nrow(test.orgs)){ for(j in 1:nrow(weights)){ dat.temp <- dat %>% filter(Test.Org == i & Weights.Set == j) %>% select(c("dist","dist.geo","dist.mission","dist.log.expense"))

jpeg(file = paste0( "rplot",i,j,".jpg"), width = 350, height = 350)
pairs( dat.temp, 
   lower.panel=panel.smooth, upper.panel=panel.cor ,
   main = paste("Weights Set", j, "and Test Org", i))
dev.off()

} }


```{r, results = "asis"}
directories <- paste0(current.dir)

plots <- list.files(directories, pattern="*.jpg")
plots <- paste0( directories, "/", plots)

index <- 1

if(length(plots > 0)){
  p <-paste0('<table border="1">')
# #create an html table with float left/right, whatever....
  for(i in seq(1,length(plots),nrow(weights))){
    p <- paste0(p, '<tr>')

    for(j in 1:nrow(weights) ){
      p <- paste0(p, '<td height="450"><img src="',plots[i+j-1],'" height="400" width="400"/></td>')
    }
    p <- paste0(p, '</tr>')

    }
p <- paste0(p, '</table>')
}

cat(p)

This solution is a little crude as is relies on your exact file path, not relative. But it is the solution I found for a variable number of test orgs and weight sets. This way, the report is adaptable to any number of test orgs and weight sets you want to test.

  1. Our leopard seal plots can be arranged with either gridArrange or egg packages.