Add Code
Add Data Analysis
With the data added to the project folder, you can now analyze them and describe the results. For the purpose of this tutorial, we suggest to conduct a simple analysis that explores whether the bill lengths of penguins vary between sex. You can write your own or use the following example:
You can copy the following code into the results section of the manuscript:
Manuscript.qmd
Descriptive statistics of the data set are given in @tbl-descriptive-statistics and individual bill lengths are displayed in @fig-bill-length-comparison.
```{r}
#| label: "t-test"
#| echo: false
#| output: "asis"
# Load penguins data set
dat <- read.csv("data.csv")
# Remove rows with NA
dat_clean <- dat[complete.cases(dat), ]
# Treat year as categorical variable
dat_clean$year <- as.factor(dat_clean$year)
# Perform t-test
t_test_result <- t.test(
bill_length_mm ~ sex,
data = dat_clean,
var.equal = FALSE,
conf.level = 0.95
)
# Describe results
report::report(
x = t_test_result,
data = dat_clean,
rules = "gignac2016"
) |>
report::as.report_text(summary = TRUE)
```
```{r}
#| label: "tbl-descriptive-statistics"
#| echo: false
#| tbl-cap: "Descriptive Statistics"
#| apa-twocolumn: true
report::report_sample(dat_clean, by = "sex", total = FALSE) |>
knitr::kable()
```
```{r}
#| label: "fig-bill-length-comparison"
#| echo: false
#| fig-cap: "Scatter Plot of Bill Lengths by Sex With Violin Plot Showing Quartiles"
# Create ggplot object
ggplot2::ggplot(dat_clean, ggplot2::aes(x = sex, y = bill_length_mm, fill = sex), group = sex) +
ggplot2::geom_violin(
draw_quantiles = c(0.25, 0.5, 0.75),
show.legend = FALSE
) +
ggplot2::geom_jitter(width = 0.15, show.legend = FALSE) +
ggplot2::labs(x = "Sex", y = "Bill length in mm") +
ggplot2::theme_minimal()
```
This code uses some new packages, one can use renv
to view them:
Console
::status() renv
Then, install and record them with:
Console
::install()
renv::snapshot() renv
After adding the data analysis, render the manuscript again:
Terminal
quarto render Manuscript.qmd
Then, make your changes known to Git:
Terminal
git status
git add .
git commit -m "Add data analysis"
Sometimes, a data analysis requires the interaction with online services:
- Data may be collected from social network sites using their APIs1 or downloaded from a data repository, or
- an analysis may be conducted with the help of AI providers.
In these cases, make sure that the code you check in to Git does not contain any credentials that are required for accessing these services. Instead, make use of environment variables which are defined in a location that is excluded from version control. When programming with R, you can define them in a file called .Renviron
in the root of your project folder:
.Renviron
MY_FIRST_KEY="your_api_key_here"
MY_SECOND_KEY="your_api_key_here"
When you start a new session from the project folder, the file is automatically read by R and the environment variables can be accessed using Sys.getenv()
:
query_api(..., api_key = Sys.getenv("MY_FIRST_KEY"))
Make sure that .Renviron
is added to your .gitignore
file in order to exclude it from the Git repository. If you already committed a file that contains credentials, you can follow Chacon & Straub (2024).
Style Manuscript
To format manuscripts according to the requirements of a particular journal, multiple Quarto extensions are available. In the following, we will demonstrate the usage of apaquarto
, which typesets documents according to the requirements of the American Psychological Association (2020). Of course, you may also use an extension for a different journal.
apaquarto
can be installed in the project folder using the following command:
Terminal
quarto add --no-prompt wjschne/apaquarto
This downloads the extension into the folder _extensions
of your project.
Then, change the format
in the YAML header of your manuscript as follows:
Manuscript.qmd
format:
apaquarto-pdf:
documentmode: man
keep-tex: true
pdf-engine: lualatex
a4paper: true
You can now render the manuscript with the new format:
Terminal
quarto render Manuscript.qmd
If the PDF file cannot be created, try updating Quarto. It comes bundled with RStudio, however, apaquarto
sometimes requires more recent versions.
Again, make your changes known to Git:
Terminal
git status
git add .
git commit -m "Apply custom manuscript style"
Add Code Citation and Attribution
As with data, there are multiple reasons to indicate when using code by others. First, there is software which is actually copied into the own project folder. For example, this is the case for the Quarto extension that you downloaded earlier. These cases matter from a copyright perspective and you need to make sure to have permission for redistribution.
Under which license is apaquarto
made available?
apaquarto
License (Solution)
According to its GitHub page, apaquarto
is licensed under CC0 1.0. This means that it can be used and distributed even without attribution.
We recommend adding a short paragraph to LICENSE.txt
to describe its license.
LICENSE.txt
(Solution)
It is best to provide attribution even if the license does not require it.
LICENSE.txt
"apaquarto" stored in "_extensions/wjschne/apaquarto" by W. Joel Schneider available from <https://github.com/wjschne/apaquarto> is licensed under CC0 1.0: <https://creativecommons.org/publicdomain/zero/1.0/>
Again, if the license required adding the full license text, you would also need to copy it to the project folder (if not already in there).
Then, there is software that is used (e.g., during the data analysis), but not copied into the project folder. Here, questions of copyright due to redistribution do not apply.
Of course, being transparent about used software for reasons of reproducibility and academic integrity matters in any case. You can consult Figure 1 for general advice whether to cite a particular piece of software or not. As with data, citations should allow for exact identification and access. From the six “software citation principles” by Smith et al. (2016), licensed under CC BY 4.0:
1. Importance: Software should be considered a legitimate and citable product of research. Software citations should be accorded the same importance in the scholarly record as citations of other research products, such as publications and data; they should be included in the metadata of the citing work, for example in the reference list of a journal article, and should not be omitted or separated. Software should be cited on the same basis as any other research product such as a paper or a book, that is, authors should cite the appropriate set of software products just as they cite the appropriate set of papers.
5. Accessibility: Software citations should facilitate access to the software itself and to its associated metadata, documentation, data, and other materials necessary for both humans and machines to make informed use of the referenced software.
6. Specificity: Software citations should facilitate identification of, and access to, the specific version of software that was used. Software identification should be as specific as necessary, such as using version numbers, revision numbers, or variants such as platforms.
In practice, you would identify all pieces of software the project relies on. A few of them are obvious, such as R itself, Quarto, and the \(\TeX\) distribution we installed before. Then there are the individual R packages2, Quarto extensions, and \(\TeX\) packages. All of them, in turn, may have dependencies and it is up to you decide when not to dig deeper. For example, some R packages are only thin wrappers around other R packages or around system dependencies which also might deserve credit. A system dependency is additional software that you require on your computer apart from the R package.
Now, add references for the software you would like to cite to the manuscript. In the following, we will demonstrate this for R and all R packages by using the R package grateful
. For arbitrary software, you can use CiteAs or the DOI Citation Formatter to create appropriate citations.
Add the following code chunk to the end of the discussion in the manuscript:
Manuscript.qmd
```{r}
#| echo: false
grateful::cite_packages(
output = "paragraph",
out.dir = ".",
omit = NULL,
dependencies = TRUE,
passive.voice = TRUE,
bib.file = "grateful-refs"
)
```
This will automatically create a paragraph citing all used packages and generate the bibliography file grateful-refs.bib
.3 Then, in the YAML header, add grateful-refs.bib
by setting the bibliography
as follows:
Manuscript.qmd
bibliography:
- Bibliography.bib
- grateful-refs.bib
Use renv
to view, install, and record the newly used package:
Console
::status()
renv::install()
renv::snapshot() renv
Finally, render the document again and commit the changes:
Terminal
quarto render Manuscript.qmd
git status
git add .
git commit -m "Add software citation"
Coding Best Practices
Although we provide you with example code in this tutorial, a few things remain to be said about best practices when it comes to writing code that is readable and maintainable.
Use project-relative paths. When you refer to a file within your project folder, write paths relative to the root (the uppermost folder in your project). For example, don’t write
C:/Users/Public/Documents/my_project/images/result.png
, instead writeimages/result.png
.Keep it simple. Add complexity only when you must. Whenever there’s a boring way to do something and a clever way, go for the boring way. If the code grows increasingly complex, refactor it into separate functions and files.
Don’t repeat yourself. Use variables and functions before you start to write (or copy-paste) the same thing twice.
Use comments to explain why you do things. The code already shows what you do. Use comments to summarize it and explain why you do it.
Don’t reinvent the wheel. With R, chances are that what you need to do is greatly facilitated by a package from one of many high-quality collections such as rOpenSci, r-lib, Tidyverse, or fastverse.
Think twice about your dependencies. Every dependency increases the risk of irreproducibility in the future. Prefer packages that are well-maintained and light on dependencies4. We also recommend you to read “When should you take a dependency?” by Wickham & Bryan (2023).
Fail early, often, and noisily. Whenever you expect a certain state, use assertions to be sure. In R, you can use
stopifnot()
to make sure that a condition is actually true.Test your code. Test your code with scenarios where you know what the result should be. Turn bugs you discovered into test cases. Use linting tools5 to identify common mistakes in your code, for example, the R package
lintr
.Read through a style guide and follow it. A style guide is a set of stylistic conventions that improve the code quality. R users are recommended to read Wickham’s (2022) “Tidyverse style guide” and use the R package
styler
. Python users may benefit from reading the “Style Guide for Python Code” by Rossum et al. (2013). And even if you don’t follow a style guide, be consistent.
This is only a brief summary and there is much more to be learned about coding practices. If you want to dive deeper we recommend the following resources:
- “Tidy design principles” (Wickham, 2023)
- “The Good Research Code Handbook” (Mineault & Nozawa, 2021)
- “Quality assurance of code for analysis and research” (UK Government Analytical Community, 2020)
- “The Art of UNIX Programming” (Raymond, 2003)
“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”
— Fowler et al. (1999), p. 15
The Last Mile
renv
only records the versions of R packages and of R itself. This means that everything we have not decided to cite or attribute is not documented anywhere. We will cover system dependencies when creating a README
. For now, however, there is one simple step you can take to record the version of Quarto (and a few other dependencies). Do run the following:
Terminal
quarto use binder
This will create a few additional files which facilitate reconstructing the computational environment in the future.6 As always, commit your changes:
Terminal
git status
git add .
git commit -m "Add repo2docker config"
References
Footnotes
An application programming interface provides the capability to interact with other software using a programming language.↩︎
By default,
renv
avoids copying them into the project folder. And even that happens (e.g., by usingrenv::isolate()
) they are excluded from Git by default.↩︎Note that this automatic detection can miss packages in some circumstances, therefore always verify the rendered result.↩︎
You can use the function
pak::pkg_deps()
to count the total number of package dependencies in R.↩︎A linting tool analyzes your code without actually running it. Therefore, this process is also called static code analysis.↩︎
Either using repo2docker or the public binder service.↩︎