A Rant on R and the Melt Function in R
Zürich, Schweiz
I need to be honest: I find the documentation for R frustrating, particularly the API documentation. From the perspective of a professional software engineer, much of the API documentation is unhelpful. There are several common problems:
- What kind of input does the function accept?
- What kind of output does the function produce?
- What does the function actually do? I’ll freely admit that I am neither a mathematician nor a statistician, so perhaps that could hurt.
Note: You could make an argument that static typing would help with this, and you’d be right. The problem is that is not R.
The only thing that seems consistent about is its inconsistency. I’m not alone in feeling that, as there’s a long history of loathing of the R Language:
- https://www.burns-stat.com/pages/Tutor/R_inferno.pdf
- https://arrgh.tim-smith.us/
- https://github.com/ReeceGoding/Frustration-One-Year-With-R
But, anyway, here we are, and here I am. I have a motivating example of frustration from my day-to-day experience.
There’s a function from reshape2 that gets my ire: melt.
It’s been something I’ve used a lot lately. I try not to be a copy-and-paste
programmer, but sometimes I need to rely on the structure of existing
solutions and documentation, and melt has been a staple of these documents
due to the structure of the data I have been working with. Let’s see what the
documentation about melt says:
This the generic melt function. See the following functions for the details about different data structures:
How on Earth am I supposed to make sense of what that means? It makes aa
little more sense when contextualized with what I read from reshape2’s
documentation:
Title Flexibly Reshape Data: A Reboot of the Reshape Package … Description Flexibly restructure and aggregate data using just two functions: melt and ‘dcast’ (or ‘acast’).
So melt in some way restructures the data? Great. But how, and what kind of
restructuring should I anticipate?
Well, let’s try to improve our understanding of what this function does visually.
Let’s suppose we have a data frame that has two columns named after siloed but mutually-compatible data streams that can be aggregated together (like temperature observations):
| |
The data looks like this:
| twin_cities | zuerich |
|---|---|
| -5 | 3 |
| 0 | 6 |
| 1 | 4 |
Let’s suppose we want to restructure df.temps into something where we
identify locality by the value of the column, not the column’s name. This
is where melt comes in:
| |
The melted data looks like this:
| variable | value |
|---|---|
| twin_cities | -5 |
| twin_cities | 0 |
| twin_cities | 1 |
| zuerich | 3 |
| zuerich | 6 |
| zuerich | 4 |
Note: The column names twin_cities and zuerich are transposed into the
new column variable and the respective values for those columns are seen now
in value.
You might wonder why this somewhat denormalized form could be preferable? It
works great with ggplot2 to lowercase-f facet the data:
| |

Now let’s adapt that original data frame to add a column that identifies the
row like a timestamp (ts), because this becomes interesting.
| |
It looks similar to the original:
| ts | twin_cities | zuerich |
|---|---|---|
| 2024-03-03 | -5 | 3 |
| 2024-03-04 | 0 | 6 |
| 2024-03-05 | 1 | 4 |
We can melt that data, and suddenly it is indexable with ts as follows:
| |
Which is tabularly:
| ts | variable | value |
|---|---|---|
| 2024-03-03 | twin_cities | -5 |
| 2024-03-04 | twin_cities | 0 |
| 2024-03-05 | twin_cities | 1 |
| 2024-03-03 | zuerich | 3 |
| 2024-03-04 | zuerich | 6 |
| 2024-03-05 | zuerich | 4 |
And now a nice time series can be produced:
| |

But back to the question at-hand: documentation quality in R. Python
Pandas has an analogue for melt with pandas.melt. Let’s compare the
documentation:
Unpivot a DataFrame from wide to long format, optionally leaving identifiers set.
This function is useful to massage a DataFrame into a format where one or more columns are identifier variables (id_vars), while all other columns, considered measured variables (value_vars), are “unpivoted” to the row axis, leaving just two non-identifier columns, ‘variable’ and ‘value’.
That documentation fragment isn’t perfect, but it’s infinitely better than
reshape2’s. So a call of action to the R community: please improve
the documentation and accessibility of high-touch APIs.
- Note-to-Self (8)
- R (3)
- Rant (2)