Site icon R-bloggers

Sweave Tutorial 2: Batch Individual Personality Reports using R, Sweave, and LaTeX

[This article was first published on Jeromy Anglim's Blog: Psychology and Statistics, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

This post documents an example of using Sweave to generate individualised personality reports based on responses to a personality test. Each report provides information on both the responses of the general sample and responses of the specific respondent. All source code is provided, and selected aspects are discussed, including makefiles use of \Sexpr, figures, and LaTeX tables using Sweave.

Overview

All source code is available on GitHub:

Three examples of compiled PDF reports can be viewed as follows: ID1ID2and ID4.

The resulting report is a simple proof of concept example.

Discussion of Source Code

makefile

outputDir = .output
backupDir = .backup

test:
    -mkdir $(outputDir)
    Rscript --verbose run1test.R  

test5:
    -mkdir $(outputDir)
    Rscript --verbose run5test.R  


runall:
    -mkdir $(outputDir)
    Rscript --verbose runAll.R  

clean:
    -rm $(outputDir)/*

backup:
    -mkdir $(backupDir)
    cp $(outputDir)/Report_Template_ID*[0123456789].pdf --target-directory=$(backupDir)

main.R

main.R loads external functions and packages, imports data, imports metadata and processes the data.

# Import Data
ipip <-read.delim("data/ipip.tsv")
ipip<-read.delim("meta/ipipmeta.tsv")
ipipscales <- read.delim("meta/ipipscales.tsv")

Test scores are calculated using the function score.items.

ipipstats <- psych::score.items(ipipmeta[,ipipscales$scale], 
        ipip[,ipipmeta[,"variable"]],
        min = 1, max = 5)

Run.R

source("main.R", echo = TRUE)
id <- NULL
exportReport <- function(x) {
    id <<- x
    fileStem <- "Report_Template"
    file.copy("Report_Template.Rnw",
            paste(".output/", fileStem, "_ID", id, ".Rnw", sep =""),
            overwrite = TRUE)
    file.copy("Sweave.sty", ".output/Sweave.sty", overwrite = TRUE)
    setwd(".output")
    Sweave(paste(fileStem, "_ID", id, ".Rnw", sep =""))
    tools::texi2dvi(paste(fileStem, "_ID", id, ".tex", sep =""), pdf = TRUE)
    setwd("..")
}

Report_Template.Rnw

Incorporating a figure using Sweave

\begin{figure}
<<plot_scale_distributions, fig=true>>=
plotScale <- function(ipipscale) {
    ggplot(ipip, aes_string(x=ipipscale["scale"])) + 
        scale_x_continuous(limits=c(1, 5),
            name = ipipscale["name"]) +
        scale_y_continuous(name = "", labels ="",   breaks = 0) +
        geom_density(fill="green", alpha = .5) +
        geom_vline(xintercept = ipip[ipip$id %in% id, ipipscale["scale"]],
                size=1) 
}


scaleplots <-   apply(ipipscales, 1, function(X) plotScale(X))

arrange(scaleplots[[1]], 
        scaleplots[[2]],
        scaleplots[[3]],
        scaleplots[[4]],
        scaleplots[[5]],
        ncol=3)
@
\caption{Figures show distributions of scores of each personality factor
in the norm sample.
Higher scores mean greater levels of the factor. 
The black vertical line indicates your score.}
\end{figure}

Preparing a formatted table in R for LaTeX

<<prepare_table>>=
ipiptable <- list()
ipiptable$colnames <- c("item", "scaleF", "text", "meanF",
        "sdF", "is1F", "is2F", "is3F", "is4F", "is5F")
ipiptable$cells <- ipipsummary[,ipiptable$colnames ]
ipiptable$cells$item <- paste(ipiptable$cells$item, ".", sep="")

# assign actual respones to table
ipiptable$cells[,c("is1F", "is2F", "is3F", "is4F", "is5F")] <-
        sapply(1:5, function(X)
        ifelse(as.numeric(ipip[ipip$id %in% id, ipipmeta$variable]) == X, 
                paste("*", ipiptable$cells[[paste("is", X, "F", sep ="")]], sep =""),
                ipiptable$cells[[paste("is", X, "F", sep ="")]]))


ipiptable$cellsF <- as.matrix(ipiptable$cells) 

ipiptable$cellsF <- ipiptable$cellsF[order(ipiptable$cellsF[, "scaleF"]), ]

ipiptable$row1 <- c("", "Scale", "Item Text", 
        "M", "SD", "VI\\%", "MI\\%", "N\\%", "MA\\%", "VA\\%")

ipiptable$table <- rbind(ipiptable$row1, ipiptable$cellsF)
ipiptable$tex <- paste(
        apply(ipiptable$table, 1, function(X) paste(X, collapse = " & ")), 
        "\\\\")
for(i in c(41, 31, 21, 11, 1)) {
    ipiptable$tex <- append(ipiptable$tex, "\\midrule", after=i)
}
ipiptable$tex1 <- ipiptable$tex[c(1:34)]
ipiptable$tex2 <- ipiptable$tex[c(1,35:56)]

Don’t Repeat Yourself Principle using R and Sexpr{}

ipiptable$caption <-
        "Response options were 
1 = (V)ery (I)naccurate, 
2 = (M)oderately (I)naccurate,
3 = (N)either Inaccurate nor Accurate, 
4 = (M)oderately (A)ccurate
5 = (V)ery (A)ccurate.
Thus, VI\\\\% indicates the percentage of the norm sample 
        giving a response indicating that the item is a Very Inaccurate
description of themselves.
Your response is indicated with an asterisk (*)."

Incorporating the tex formatted table using R Code chunks

\begin{table}
\begin{adjustwidth}{-1cm}{-1cm}
\caption{Table of results for (A)greeableness, (C)onscientiousness
and (E)motional (S)tability items.
\Sexpr{ipiptable[["caption"]]}} 
\begin{center}
\begin{tabular}{rrp{4cm}rrrrrrr}
\toprule
<<table_part1, results=tex>>=
cat(ipiptable$tex1, sep="\n") 
@
\bottomrule
\end{tabular}
\end{center}
\end{adjustwidth}
\end{table}

Additional Resources

To leave a comment for the author, please follow the link and comment on their blog: Jeromy Anglim's Blog: Psychology and Statistics.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.