Skip to content

Commit 50e056f

Browse files
authored
vignettes: avoid using _ or . in header IDs (#6784)
* vignettes: avoid using _ or . in header IDs data.table-intro on CRAN: <h3 id="h-great-but-how-can-i-refer-to-columns-by-names-in-j-like-in-a-data-frame" #refer_j>h) Great! But how can I refer to columns by names in <code>j</code> (like in a <code>data.frame</code>)?</h3> <h4 id="how-can-we-calculate-the-number-of-trips-for-each-origin-airport-for-carrier-code-quot-aa-quot" #origin-.N>– How can we calculate the number of trips for each origin airport for carrier code <code>&quot;AA&quot;</code>?</h4> <h4 id="how-can-we-get-the-total-number-of-trips-for-each-origin-dest-pair-for-carrier-code-quot-aa-quot" #origin-dest-.N>– How can we get the total number of trips for each <code>origin, dest</code> pair for carrier code <code>&quot;AA&quot;</code>?</h4> This is not valid HTML and the links to these headers don't work. "Intro" seems to be the only vignette affected. * Add a linter to validate vignette heading ids This doesn't parse the full range of Pandoc's header_attributes extension (one shouldn't be using regular expressions for that), but at least it captures the existing mistakes without obvious false positives. * Fix the heading ids in 'Introduction à data.table'
1 parent b089b74 commit 50e056f

File tree

3 files changed

+36
-10
lines changed

3 files changed

+36
-10
lines changed

.ci/linters/md/heading_id_linter.R

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
any_mismatch = FALSE
2+
3+
# ensure that ids are limited to alphanumerics and dashes
4+
# (in particular, dots and underscores break the links)
5+
check_header_ids = function(md) {
6+
# A bit surprisingly, some headings don't start with a letter.
7+
# We're interested in those that set an id to link to, i.e., end with {#id}.
8+
heading_captures = regmatches(md, regexec("^#+ \\S.*[{]#([^}]*)[}]$", md))
9+
lines_with_id = which(lengths(heading_captures) > 0)
10+
ids = vapply(heading_captures[lines_with_id], `[`, '', 2)
11+
# ids must start with a letter and consist of alphanumerics or dashes.
12+
good_ids = grepl('^[A-Za-z][A-Za-z0-9-]*$', ids)
13+
for (line in lines_with_id[!good_ids]) cat(sprintf(
14+
"On line %d, bad heading id '%s':\n%s\n",
15+
line, heading_captures[[line]][2], heading_captures[[line]][1]
16+
))
17+
!all(good_ids)
18+
}
19+
20+
any_error = FALSE
21+
for (vignette in list.files('vignettes', pattern = "[.]Rmd$", recursive = TRUE, full.name = TRUE)) {
22+
cat(sprintf("Checking vignette file %s...\n", vignette))
23+
rmd_lines = readLines(vignette)
24+
any_error = check_header_ids(rmd_lines) || any_error
25+
}
26+
if (any_error) stop("Please fix the vignette issues above.")

vignettes/datatable-intro.Rmd

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ ans
316316

317317
We could have accomplished the same operation by doing `nrow(flights[origin == "JFK" & month == 6L])`. However, it would have to subset the entire `data.table` first corresponding to the *row indices* in `i` *and then* return the rows using `nrow()`, which is unnecessary and inefficient. We will cover this and other optimisation aspects in detail under the *`data.table` design* vignette.
318318

319-
### h) Great! But how can I refer to columns by names in `j` (like in a `data.frame`)? {#refer_j}
319+
### h) Great! But how can I refer to columns by names in `j` (like in a `data.frame`)? {#refer-j}
320320

321321
If you're writing out the column names explicitly, there's no difference compared to a `data.frame` (since v1.9.8).
322322

@@ -422,7 +422,7 @@ ans
422422
423423
We'll use this convenient form wherever applicable hereafter.
424424
425-
#### -- How can we calculate the number of trips for each origin airport for carrier code `"AA"`? {#origin-.N}
425+
#### -- How can we calculate the number of trips for each origin airport for carrier code `"AA"`? {#origin-N}
426426
427427
The unique carrier code `"AA"` corresponds to *American Airlines Inc.*
428428
@@ -435,7 +435,7 @@ ans
435435

436436
* Using those *row indices*, we obtain the number of rows while grouped by `origin`. Once again no columns are actually materialised here, because the `j-expression` does not require any columns to be actually subsetted and is therefore fast and memory efficient.
437437

438-
#### -- How can we get the total number of trips for each `origin, dest` pair for carrier code `"AA"`? {#origin-dest-.N}
438+
#### -- How can we get the total number of trips for each `origin, dest` pair for carrier code `"AA"`? {#origin-dest-N}
439439

440440
```{r}
441441
ans <- flights[carrier == "AA", .N, by = .(origin, dest)]
@@ -483,7 +483,7 @@ We'll learn more about `keys` in the [`vignette("datatable-keys-fast-subset", pa
483483

484484
### c) Chaining
485485

486-
Let's reconsider the task of [getting the total number of trips for each `origin, dest` pair for carrier *"AA"*](#origin-dest-.N).
486+
Let's reconsider the task of [getting the total number of trips for each `origin, dest` pair for carrier *"AA"*](#origin-dest-N).
487487

488488
```{r}
489489
ans <- flights[carrier == "AA", .N, by = .(origin, dest)]
@@ -583,7 +583,7 @@ We are almost there. There is one little thing left to address. In our `flights`
583583

584584
Using the argument `.SDcols`. It accepts either column names or column indices. For example, `.SDcols = c("arr_delay", "dep_delay")` ensures that `.SD` contains only these two columns for each group.
585585

586-
Similar to [part g)](#refer_j), you can also specify the columns to remove instead of columns to keep using `-` or `!`. Additionally, you can select consecutive columns as `colA:colB` and deselect them as `!(colA:colB)` or `-(colA:colB)`.
586+
Similar to [part g)](#refer-j), you can also specify the columns to remove instead of columns to keep using `-` or `!`. Additionally, you can select consecutive columns as `colA:colB` and deselect them as `!(colA:colB)` or `-(colA:colB)`.
587587

588588
Now let us try to use `.SD` along with `.SDcols` to get the `mean()` of `arr_delay` and `dep_delay` columns grouped by `origin`, `dest` and `month`.
589589

vignettes/fr/datatable-intro.Rmd

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ ans
312312

313313
On aurait pu faire la même opération en écrivant `nrow(flights[origin == "JFK" & month == 6L])`. Néanmoins il aurait fallu d'abord dissocier la `data.table` entière en fonction des *indices de lignes* dans `i` *puis* renvoyer les lignes en utilisant `nrow()`, ce qui est inutile et pas efficace. Nous aborderons en détails ce sujet et d'autres aspects de l'optimisation dans la vignette *architecture de `data.table`*.
314314

315-
### h) Super ! Mais comment référencer les colonnes par nom dans `j` (comme avec un `data.frame`) ? {#refer_j}
315+
### h) Super ! Mais comment référencer les colonnes par nom dans `j` (comme avec un `data.frame`) ? {#refer-j}
316316

317317
Si vous imprimez le nom des colonnes explicitement, il n'y a pas de différence avec un `data.frame` (depuis v1.9.8).
318318

@@ -418,7 +418,7 @@ ans
418418
419419
Nous utiliserons cette forme pratique chaque fois que cela sera possible.
420420
421-
#### -- Comment calculer le nombre de voyages au départ de chaque aéroport pour le transporteur ayant le code `"AA"`? {#origin-.N}
421+
#### -- Comment calculer le nombre de voyages au départ de chaque aéroport pour le transporteur ayant le code `"AA"`? {#origin-N}
422422
423423
Le code unique de transporteur `"AA"` correspond à *American Airlines Inc.*
424424
@@ -431,7 +431,7 @@ ans
431431

432432
* En utilisant ces *index de ligne*, nous obtenons le nombre de lignes groupées par `origine`. Une fois de plus, aucune colonne n'est matérialisée ici, car l'expression `j' ne nécessite aucune colonne pour définir le sous-ensemble et le calcul est donc rapide et peu gourmand en mémoire.
433433

434-
#### -- Comment obtenir le nombre total de voyages pour chaque paire `origin, dest` du transporteur ayant pour code `"AA"`? {#origin-dest-.N}
434+
#### -- Comment obtenir le nombre total de voyages pour chaque paire `origin, dest` du transporteur ayant pour code `"AA"`? {#origin-dest-N}
435435

436436
```{r}
437437
ans <- flights[carrier == "AA", .N, by = .(origin, dest)]
@@ -479,7 +479,7 @@ Nous en apprendrons plus au sujet des `clés` dans la vignette *Clés et sous-en
479479

480480
### c) Chaînage
481481

482-
Considérons la tâche consistant à [récupérer le nombre total de voyages pour chaque couple `origin, dest` du transporteur *"AA"*](#origin-dest-.N).
482+
Considérons la tâche consistant à [récupérer le nombre total de voyages pour chaque couple `origin, dest` du transporteur *"AA"*](#origin-dest-N).
483483

484484
```{r}
485485
ans <- flights[carrier == "AA", .N, by = .(origin, dest)]
@@ -579,7 +579,7 @@ Nous y sommes presque. Il reste encore une petite chose à régler. Dans notre `
579579

580580
En utilisant l'argument `.SDcols`. Il accepte soit des noms soit des indices de colonnes. Par exemple, `.SDcols = c("arr_delay", "dep_delay")` permet que `.SD` ne comporte que ces deux colonnes pour chaque groupe.
581581

582-
De la même manière que [part g)](#refer_j), vous pouvez également spécifier les colonnes à supprimer au lieu des colonnes à garder en utilisant le `-` ou `!`. De plus, vous pouvez sélectionner des colonnes consécutives avec `colA:colB` et les désélectionner avec `!(colA:colB)` ou `-(colA:colB)`.
582+
De la même manière que [part g)](#refer-j), vous pouvez également spécifier les colonnes à supprimer au lieu des colonnes à garder en utilisant le `-` ou `!`. De plus, vous pouvez sélectionner des colonnes consécutives avec `colA:colB` et les désélectionner avec `!(colA:colB)` ou `-(colA:colB)`.
583583

584584
Maintenant essayons d'utiliser `.SD` avec `.SDcols` pour obtenir la moyenne `mean()` des colonnes `arr_delay` et `dep_delay` groupées par `origin`, `dest` et `month`.
585585

0 commit comments

Comments
 (0)