Skip to Content
Course content

237: Literate Programming Principles in R

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I was looking back at a script I wrote six months ago—a data cleaning pipeline for some atmospheric sensor data—and I realized I had no idea why I chose a specific window size for my rolling average. I had a comment that said # Calculate rolling mean, which is about as helpful as a sign that says "This is a sign."

That's where we hit the wall with traditional scripting. We spend so much time writing the how (the code) that we forget to document the why (the reasoning). This is where Literate Programming comes in. In the R world, we mostly do this through R Markdown or Quarto. It's not just about "adding comments"; it's about treating the code as a supporting actor to the narrative.

The frustration of the "Comment Wall"

Let's look at how I usually start. I'll just throw everything into a standard .R script. Imagine we're trying to smooth out some noisy temperature data to find a trend.

# Load library
library(zoo)

# Create data
temp <- c(22.1, 22.5, 21.8, 35.0, 22.2, 21.9, 22.0, 10.1, 22.3) # 35 and 10 are outliers

# Rolling mean
smooth_temp <- rollmean(temp, k = 3, fill = NA)

# Plot
plot(smooth_temp)

If you're the one who wrote this, it makes sense. But look at that k = 3. Why 3? Why not 5? Why did I decide that 35.0 was an outlier? The code tells me what happened, but it doesn't tell me the story of the decision. If I share this with you, you're just guessing my intent.

Weaving narrative into the logic

I'm going to move this into an R Markdown (.Rmd) format. Instead of fighting with # symbols, I'm going to write this as if I'm explaining the problem to you in real-time. I'll create a "chunk" for the code and leave the surrounding space for the prose.

I'll start by explaining the data source. I'll write: "The sensors in the north wing are prone to occasional voltage spikes, which manifest as impossible temperature jumps (e.g., 35°C in a refrigerated room). To handle this, I'll use a small rolling window to dampen the noise."

```{r}
library(zoo)
temp <- c(22.1, 22.5, 21.8, 35.0, 22.2, 21.9, 22.0, 10.1, 22.3)
smooth_temp <- rollmean(temp, k = 3, fill = NA)
```

Now, the code is a subset of the explanation. I've just turned a "script" into a "document." The magic here is that the code is still executable, but the reasoning is first-class.

Cleaning up the noise

Here is where I usually run into a problem. When I knit this to a report, R loves to be chatty. If I load a library or run a function that triggers a warning, it prints that ugly warning right in the middle of my beautiful narrative. It breaks the flow.

I tried running the rollmean chunk, and I got a warning about NA values. It looks like this in the output: Warning message: In rollmean(...) : NA's introduced by.... That's distracting. I don't want the reader to worry about the technicality of how zoo handles edges; I want them to see the resulting trend.

I can adjust the "chunk options" to curate the experience. By adding warning=FALSE and message=FALSE to the top of the chunk, I'm essentially telling R: "I know this is happening, but it's not relevant to the story I'm telling."

```{r, warning=FALSE, message=FALSE}
# Now the output is clean, and only the result remains
smooth_temp <- rollmean(temp, k = 3, fill = NA)
plot(smooth_temp, type = "l", main = "Smoothed Temperature Trend")
```

I've just moved from "dumping code" to "authoring a report." I can even use echo=FALSE if I want to show the plot but hide the actual R code, which is great for stakeholders who don't care about the syntax but care deeply about the result.

The "Aha" moment

The real shift happens when you realize that Literate Programming isn't about making things look pretty—it's about reproducibility. If I change the window size from k = 3 to k = 5, I can immediately write a paragraph below the plot explaining why the trend now looks too flat. The code and the critique of the code exist in the same space.

You aren't just writing a program that processes data; you're writing a paper that happens to run its own examples. It changes the way you think about your workflow. You stop thinking in "steps" and start thinking in "arguments."




📋 Practical Task

Converting the "Wildfire Smoke Analysis" Script to a Literate Document

You have been handed a raw R script used to analyze air quality during a wildfire event. The script works, but the researcher who wrote it left no explanation for their decisions, and the output is cluttered with warnings.

The raw script:

library(dplyr)
aqi_data <- c(45, 52, 180, 210, 195, 40, 38, 55) 
# The researcher decided to filter out values below 50 to focus on 'unhealthy' air
filtered_data <- aqi_data[aqi_data > 50]
mean_unhealthy <- mean(filtered_data)
print(mean_unhealthy)

Your Task:

  1. Create a Quarto or R Markdown structure for this analysis.
  2. Convert the code into a literate format. Instead of just comments, write a narrative paragraph explaining why filtering out values below 50 is necessary for this specific study.
  3. Wrap the code in a chunk that suppresses any potential messages or warnings (using chunk options).
  4. Add a final narrative section that interprets the mean_unhealthy result in plain English, explaining what this number actually means for public health.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.