Skip to contents

Introduction

The milestoneR package provides R access to the Milestones Project database, a comprehensive collection of important events in the history of data visualization. This vignette demonstrates how to:

  • Access milestone data
  • Search and filter milestones
  • Display results in various formats
  • Explore relationships between milestones, authors, and references

Loading the package

Accessing data

The package provides accessor functions for all main database tables:

# Get all milestones
ms <- milestone()
cat("Total milestones:", nrow(ms), "\n")
#> Total milestones: 297

# Get all authors
aut <- authors()
cat("Total authors:", nrow(aut), "\n")
#> Total authors: 268

# Get all references
refs <- reference()
cat("Total references:", nrow(refs), "\n")
#> Total references: 352

# Get keywords, subjects, and aspects
kw <- keyword()
subj <- subject()
asp <- aspect()

cat("Keywords:", nrow(kw), "\n")
#> Keywords: 335
cat("Subjects:", nrow(subj), "\n")
#> Subjects: 4
cat("Aspects:", nrow(asp), "\n")
#> Aspects: 4

Exploring milestones

Let’s look at the structure of the milestone data:

# View column names
names(ms)
#>  [1] "mid"               "slug"              "date_from_numeric"
#>  [4] "date_from"         "date_to_numeric"   "date_to"          
#>  [7] "tag"               "description"       "location"         
#> [10] "add_date"          "modified_date"     "status"           
#> [13] "note"              "extra"

# Look at a few key fields
ms |>
  subset(select = c(mid, date_from, tag, location)) |>
  head(10)
#>    mid date_from                          tag                  location
#> 1    1     -6200            Oldest known map?   Museum at Konya, Turkey
#> 2    2    550 BC               1st world map?                    Turkey
#> 3    3    366 BC                1st route map                      <NA>
#> 4    4      -240   Diameter of earth measured                     Libya
#> 5    5    170 BC       Invention of parchment Pergamon, Bergama, Turkey
#> 6    6      -134                   Star chart                    Turkey
#> 7    7       105           Invention of paper                     China
#> 8    8        90           Latitude/longitude                      <NA>
#> 9    9       950 Diagram: planetary movements                    Europe
#> 10  10      1280  Diagram: paired comparisons                     Spain

Date range coverage

# Date range of milestones
cat("Earliest milestone:", min(ms$date_from_numeric, na.rm = TRUE), "\n")
#> Earliest milestone: -6200
cat("Most recent milestone:", max(ms$date_from_numeric, na.rm = TRUE), "\n")
#> Most recent milestone: 2009

# Count by century
ms$century <- (ms$date_from_numeric %/% 100) * 100
ms$century |>
  table() |>
  print()
#> 
#> -6200  -600  -400  -300  -200  -100     0   100   900  1200  1300  1400  1500 
#>     1     1     1     1     2     1     2     1     1     1     3     2    11 
#>  1600  1700  1800  1900  2000 
#>    27    34    98   105     5

Searching milestones

The package provides three specialized search functions.

Search across milestone fields (description, tag, note):

# Find milestones mentioning "statistical"
stat_ids <- search_milestones("statistical")
cat("Found", length(stat_ids), "milestones mentioning 'statistical'\n")
#> Found 51 milestones mentioning 'statistical'

# Show the first few
head(stat_ids)
#> [1] 36 38 55 76 94 99

# Use regex to find "chart" OR "graph"
chart_ids <- search_milestones("chart|graph", fields = c("description", "tag"))
cat("\nFound", length(chart_ids), "milestones with 'chart' or 'graph'\n")
#> 
#> Found 132 milestones with 'chart' or 'graph'

# Search only in tags for items marked as "1st" (first)
first_ids <- search_milestones("^1st", fields = "tag")
cat("\nFound", length(first_ids), "milestone tags starting with '1st'\n")
#> 
#> Found 24 milestone tags starting with '1st'

Search by keywords

# Find milestones tagged with "contour"
contour_ids <- search_keywords("contour")
cat("Milestones with 'contour' keyword:", paste(contour_ids, collapse = ", "), "\n")
#> Milestones with 'contour' keyword: 65, 117, 145, 83, 53

# Search for statistical keywords
stat_kw_ids <- search_keywords("statistic")
cat("\nMilestones with statistical keywords:", length(stat_kw_ids), "\n")
#> 
#> Milestones with statistical keywords: 10

Search by author

# Find William Playfair's milestones
playfair_ids <- search_authors("Playfair")
cat("William Playfair's milestones:", paste(playfair_ids, collapse = ", "), "\n")
#> William Playfair's milestones: 80, 89

# Find all authors named John
john_ids <- search_authors("John", name_fields = "givennames")
cat("\nMilestones by authors named John:", length(john_ids), "\n")
#> 
#> Milestones by authors named John: 20

# Search only last names
nightingale_ids <- search_authors("Nightingale", name_fields = "lname")
cat("\nMilestones by Nightingale:", paste(nightingale_ids, collapse = ", "), "\n")
#> 
#> Milestones by Nightingale: 129

Filtering by date and category

Combine direct data frame operations with search functions:

# Milestones from the 1800s
ms_1800s <- ms |>
  subset(date_from_numeric >= 1800 & date_from_numeric < 1900)
cat("Milestones from 1800-1899:", nrow(ms_1800s), "\n")
#> Milestones from 1800-1899: 98

# Early milestones (before 1700)
early <- ms |>
  subset(date_from_numeric < 1700)
cat("Milestones before 1700:", nrow(early), "\n")
#> Milestones before 1700: 55

# Milestones in France
france <- ms |>
  subset(!is.na(location) & grepl("France", location, ignore.case = TRUE))
cat("Milestones in France:", nrow(france), "\n")
#> Milestones in France: 45

Filtering by subject and aspect

Using the linking tables:

# Get milestones by subject
m2subj <- milestone2subject()

# Milestones with "Physical" subject
physical_mids <- m2subj |>
  subset(subject == "Physical") |>
  getElement("mid")
cat("Milestones with 'Physical' subject:", length(physical_mids), "\n")
#> Milestones with 'Physical' subject: 77

# Get milestones by aspect
m2asp <- milestone2aspect()

# Milestones with "Cartography" aspect
carto_mids <- m2asp |>
  subset(aspect == "Cartography") |>
  getElement("mid")
cat("Milestones with 'Cartography' aspect:", length(carto_mids), "\n")
#> Milestones with 'Cartography' aspect: 44

# Combine: Cartography AND Physical
combined <- intersect(physical_mids, carto_mids)
cat("\nMilestones that are both Physical and Cartography:", length(combined), "\n")
#> 
#> Milestones that are both Physical and Cartography: 20

Displaying results

The package provides several print functions with various output formats: "text", "html", "markdown", "cli" (enhanced console output).

Printing individual milestones

# Print Halley's 1701 contour map in text format
halley <- ms |>
  subset(date_from_numeric == 1701)
print_milestone(halley$mid)
#> [1701] 1st contour map?
#> Authors: Edmond Halley
#> 
#> Contour maps showing curves of equal value (an isogonic map, lines of equal magnetic declination for the world, possibly the first contour map of a data-based variable)
#> 
#> Keywords: contour map, isogonic
#> Subjects: Physical
#> Aspects: Statistics & Graphics
#> 
#> Media:
#>   - [link] National maritime museum, Halley magnetic chart
#>   - [image] Halley isogonic map
#>   - [link] Halley biography
#>   - [link] Geomagnetism: early concept of the North Magnetic Pole - The concept of the North Magnetic Pole arose from the desire of early European navigators to explain the directional properties of the compass. Chines used compass at least as early as the 1st century and it was imported to Europe in the 12th century.
#> 
#> References:
#>   - Halley, Edmund. (1701). "The Description and Uses of a New, and Correct Sea-Chart of the Whole World, Shewing Variations of the Compass"
#>   - Abbott, Edwin A. (1884). "Flatland: A Romance of Many Dimensions". Cutchogue, NY: Buccaneer Books. [(1976 reprint of the 1884 edition)]

Different output formats

# HTML format (useful for R Markdown documents)
print_milestone(53, result = "html")

# Markdown format
print_milestone(53, result = "md")

# Enhanced CLI format with clickable links (in modern terminals)
print_milestone_cli(53)

Printing multiple milestones

# Print Playfair's milestones
print_milestone_cli(playfair_ids)

Selective sections

You can control which sections to display:

# Show only authors, media, and references
print_milestone(53, include = c("authors", "media", "references"))

Search with formatted output

Combine search with immediate formatted display:

# Find and print Florence Nightingale's work
search_milestones("Florence Nightingale",
                  fields = "description",
                  output = "print")
#> [1829] Polar-area charts
#> Authors: André Michel Guerry
#> 
#> Polar-area charts (predating those by Florence Nightingale cite{Nightingale:1857}), showing frequency of events for cyclic phenomena
#> 
#> Location: France
#> Keywords: chart!polar, coxcomb
#> Subjects: Physical
#> Aspects: Statistics & Graphics
#> 
#> Media:
#>   - [image] Guerry's polar diagrams
#>   - [image] Guerry barcharts and polar diagrams
#> 
#> Note: The plate shows six polar diagrams for daily phenomena: direction of the wind in 8 sectors, births and deaths by hour of theday.
#> 
#> References:
#>   - Balbi, Adriano & Guerry, André-Michel. (1829). "Tableau des Variations météorologique comparées aux phénomènes physiologiques, d'aprés les observations faites à l'Obervatoire royal, et les recherches statistique les plus récentes". _Annales d'Hygiène Publique et de Médecine Légale_. 1. pp. 228-

Use helper functions to get related data for milestones.

Getting authors

# Get authors for Halley's milestone
halley_authors <- get_milestone_authors(53)
halley_authors |>
  subset(select = c(givennames, lname, birthdate, deathdate)) |>
  print()
#>   givennames  lname  birthdate  deathdate
#> 1     Edmond Halley 1656-11-08 1742-01-14

# Get authors for multiple milestones
playfair_authors <- get_milestone_authors(playfair_ids)
playfair_authors |>
  subset(select = c(givennames, lname, birthdate)) |>
  print()
#>   givennames    lname  birthdate
#> 1    William Playfair 1759-09-22
#> 2    William Playfair 1759-09-22

Getting references

# Get references for a milestone
halley_refs <- get_milestone_references(53)
halley_refs |>
  subset(select = c(rid, author, year, title)) |>
  print()
#>   rid          author year
#> 1 290  Halley, Edmund 1701
#> 2 365 Abbott, Edwin A 1884
#>                                                                                                            title
#> 1 The Description and Uses of a New, and Correct Sea-Chart of the Whole World, Shewing Variations of the Compass
#> 2                                                                         Flatland: A Romance of Many Dimensions

# Print formatted reference
print_reference(halley_refs[1, ])
#> Halley, Edmund. (1701). "The Description and Uses of a New, and Correct Sea-Chart of the Whole World, Shewing Variations of the Compass"

Getting keywords

# Get keywords for a milestone
halley_kw <- get_milestone_keywords(53)
print(halley_kw)
#>     mid kid     keyword
#> 325  53  38 contour map
#> 324  53 128    isogonic

# Get all keywords for Playfair's work
playfair_kw <- get_milestone_keywords(playfair_ids)
playfair_kw$keyword |>
  table() |>
  print()
#> 
#>    bar chart circle graph   line graph    pie chart 
#>            1            1            1            1

Getting media items

# Get media items for a milestone
halley_media <- get_milestone_media(53)
halley_media |>
  subset(select = c(miid, type, title)) |>
  print()
#>     miid  type                                                  title
#> 566 1339  link        National maritime museum, Halley magnetic chart
#> 567 1340 image                                    Halley isogonic map
#> 568 1341  link                                       Halley biography
#> 569 1342  link Geomagnetism: early concept of the North Magnetic Pole

# Check how many milestones have media
all_media <- get_milestone_media(ms$mid)
cat("Total media items:", nrow(all_media), "\n")
#> Total media items: 808
cat("Milestones with media:", length(unique(all_media$mid)), "\n")
#> Milestones with media: 256

Printing references and authors

References

# Print a reference in text format
print_reference(halley_refs[1, ])
#> Halley, Edmund. (1701). "The Description and Uses of a New, and Correct Sea-Chart of the Whole World, Shewing Variations of the Compass"

# Print as BibTeX
cat("\nAs BibTeX:\n")
#> 
#> As BibTeX:
print_reference(halley_refs[1, ], bibtex = TRUE)
#> @article{Halley:1701,
#>   author = {Halley, Edmund},
#>   title = {The Description and Uses of a New, and Correct Sea-Chart of the Whole World, Shewing Variations of the Compass},
#>   year = {1701},
#>   publisher = {Author},
#>   address = {London}
#> }

# Print multiple references
print_reference(halley_refs)
#> Halley, Edmund. (1701). "The Description and Uses of a New, and Correct Sea-Chart of the Whole World, Shewing Variations of the Compass" 
#> 
#> Abbott, Edwin A. (1884). "Flatland: A Romance of Many Dimensions". Cutchogue, NY: Buccaneer Books. [(1976 reprint of the 1884 edition)]

Authors

# Print author information
print_author(halley_authors[1, ])
#> Edmond Halley; born: Haggerston, Shoreditch, England (1656-11-08); died: Greenwich, England (1742-01-14)

# Get a specific author by name
playfair_aut <- aut |>
  subset(grepl("Playfair", lname))
print_author(playfair_aut[1, ])
#> William Playfair; born: Dundee, Scotland (1759-09-22); died: London, England (1823-02-11); [
#> ]

Example workflow: Researching a topic

Here’s a complete example of researching “contour maps” in the history of data visualization:

# 1. Search for contour-related milestones
contour_text <- search_milestones("contour", fields = c("description", "tag"))
contour_kw <- search_keywords("contour")

# Combine results (union)
contour_all <- unique(c(contour_text, contour_kw))
cat("Found", length(contour_all), "contour-related milestones\n")
#> Found 6 contour-related milestones

# 2. Get the milestone data
contour_ms <- ms |>
  subset(mid %in% contour_all)

# 3. Sort by date
contour_ms <- contour_ms[order(contour_ms$date_from_numeric), ]

# 4. Display summary
cat("\nContour map milestones chronology:\n")
#> 
#> Contour map milestones chronology:
for (i in 1:nrow(contour_ms)) {
  cat(sprintf("[%s] %s\n",
              contour_ms$date_from[i],
              contour_ms$tag[i]))
}
#> [1701] 1st contour map?
#> [1752] Contour map
#> [1795] Proto-nomogram
#> [1843] Contour map of 3D table
#> [1874] Statistical contour map
#> [1885] Correlation

# 5. Get all authors involved
contour_authors <- get_milestone_authors(contour_all)
cat("\nAuthors involved in contour mapping:\n")
#> 
#> Authors involved in contour mapping:
unique_authors <- unique(contour_authors[, c("givennames", "lname", "birthdate")])
unique_authors[order(unique_authors$birthdate), ] |>
  print()
#>       givennames    lname  birthdate
#> 3         Edmond   Halley 1656-11-08
#> 1      Phillippe   Buache 1700-02-07
#> 4           Léon  Lalanne 1811-07-03
#> 6    Louis-Léger Vauthier 1815-04-06
#> 2        Francis   Galton 1822-02-16
#> 5 Louis Ézéchiel  Pouchet       <NA>

# 6. Print detailed information for the earliest one
cat("\n--- Earliest Contour Map Milestone ---\n")
#> 
#> --- Earliest Contour Map Milestone ---
print_milestone(contour_ms$mid[1])
#> [1701] 1st contour map?
#> Authors: Edmond Halley
#> 
#> Contour maps showing curves of equal value (an isogonic map, lines of equal magnetic declination for the world, possibly the first contour map of a data-based variable)
#> 
#> Keywords: contour map, isogonic
#> Subjects: Physical
#> Aspects: Statistics & Graphics
#> 
#> Media:
#>   - [link] National maritime museum, Halley magnetic chart
#>   - [image] Halley isogonic map
#>   - [link] Halley biography
#>   - [link] Geomagnetism: early concept of the North Magnetic Pole - The concept of the North Magnetic Pole arose from the desire of early European navigators to explain the directional properties of the compass. Chines used compass at least as early as the 1st century and it was imported to Europe in the 12th century.
#> 
#> References:
#>   - Halley, Edmund. (1701). "The Description and Uses of a New, and Correct Sea-Chart of the Whole World, Shewing Variations of the Compass"
#>   - Abbott, Edwin A. (1884). "Flatland: A Romance of Many Dimensions". Cutchogue, NY: Buccaneer Books. [(1976 reprint of the 1884 edition)]

Combining filters

Create complex queries by combining multiple search strategies:

# Find statistical graphics in the 1800s
stat_ids <- search_milestones("statistical")
stat_1800s <- ms |>
  subset(mid %in% stat_ids) |>
  subset(date_from_numeric >= 1800 & date_from_numeric < 1900)

cat("Statistical graphics milestones in the 1800s:", nrow(stat_1800s), "\n")
#> Statistical graphics milestones in the 1800s: 17

# Show them
stat_1800s |>
  subset(select = c(mid, date_from, tag)) |>
  head(5) |>
  print()
#>     mid date_from                       tag
#> 94   94      1819            Choropleth map
#> 99   99      1826            Choropleth map
#> 123 123      1851         Map with diagrams
#> 124 124      1852           Graphics in law
#> 127 127      1857 Standardization of graphs

Summary statistics

Get overview statistics about the database:

# Count by subject
m2subj <- milestone2subject()
subj_counts <- table(m2subj$subject)
cat("Milestones by Subject:\n")
#> Milestones by Subject:
print(subj_counts)
#> 
#>        Human Mathematical        Other     Physical 
#>           59          131           30           77

# Count by aspect
m2asp <- milestone2aspect()
asp_counts <- table(m2asp$aspect)
cat("\nMilestones by Aspect:\n")
#> 
#> Milestones by Aspect:
print(asp_counts)
#> 
#>           Cartography                 Other Statistics & Graphics 
#>                    44                    11                   193 
#>            Technology 
#>                    50

# Most common keywords (top 10)
m2kw <- milestone2keyword()
kw_counts <- m2kw$keyword |>
  table() |>
  sort(decreasing = TRUE)
cat("\nTop 10 Keywords:\n")
#> 
#> Top 10 Keywords:
print(head(kw_counts, 10))
#> 
#>               census           line graph interactive graphics 
#>                    6                    6                    5 
#>            longitude          mosaic plot            chartbook 
#>                    5                    5                    4 
#>          contour map    coordinates!polar graphical perception 
#>                    4                    4                    4 
#>       map!choropleth 
#>                    4

# Milestones per century
century_table <- table(ms$century)
cat("\nMilestones per Century:\n")
#> 
#> Milestones per Century:
print(century_table)
#> 
#> -6200  -600  -400  -300  -200  -100     0   100   900  1200  1300  1400  1500 
#>     1     1     1     1     2     1     2     1     1     1     3     2    11 
#>  1600  1700  1800  1900  2000 
#>    27    34    98   105     5

Next steps

This vignette has covered the basics of accessing, searching, and displaying milestones data. For more advanced usage:

References

Friendly, M., Sigal, M. & Harnanansingh, D. (2015). “The Milestones Project: A Database for the History of Data Visualization.” In Kimball, M. & Kostelnick, C. (Eds.) Visible Numbers: The History of Data Visualization, Chapter 10. London, UK: Ashgate Press. preprint