library(contoso)
dplyr::glimpse(sales)
#> Rows: 7,794
#> Columns: 20
#> $ order_key <dbl> 233000, 233100, 233100, 233100, 233200, 233200, 233200, …
#> $ line_number <dbl> 0, 0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 0, 1, 2, 3, 0, 0, 1, 0,…
#> $ order_date <date> 2021-05-18, 2021-05-19, 2021-05-19, 2021-05-19, 2021-05…
#> $ delivery_date <date> 2021-05-18, 2021-05-19, 2021-05-19, 2021-05-19, 2021-05…
#> $ customer_key <dbl> 1855811, 1345436, 1345436, 1345436, 926315, 926315, 9263…
#> $ store_key <dbl> 585, 550, 550, 550, 370, 370, 370, 370, 60, 60, 60, 9999…
#> $ product_key <dbl> 1483, 499, 1512, 1490, 2512, 424, 1548, 312, 665, 623, 1…
#> $ quantity <dbl> 2, 1, 3, 3, 3, 2, 3, 2, 3, 5, 7, 1, 3, 1, 2, 3, 3, 2, 2,…
#> $ unit_price <dbl> 376.600, 148.500, 334.600, 180.600, 181.986, 404.925, 37…
#> $ net_price <dbl> 376.60000, 130.68000, 287.75600, 176.98800, 172.88670, 3…
#> $ unit_cost <dbl> 173.1800, 75.7050, 153.8740, 92.0780, 60.2980, 206.4450,…
#> $ currency_code <chr> "USD", "USD", "USD", "USD", "GBP", "GBP", "GBP", "GBP", …
#> $ exchange_rate <dbl> 1.00000, 1.00000, 1.00000, 1.00000, 0.70802, 0.70802, 0.…
#> $ gross_revenue <dbl> 753.200, 148.500, 1003.800, 541.800, 545.958, 809.850, 1…
#> $ net_revenue <dbl> 753.20000, 130.68000, 863.26800, 530.96400, 518.66010, 7…
#> $ unit_discount <dbl> 0.00000, 17.82000, 46.84400, 3.61200, 9.09930, 16.19700,…
#> $ discounts <dbl> 0.00000, 17.82000, 140.53200, 10.83600, 27.29790, 32.394…
#> $ cogs <dbl> 346.3600, 75.7050, 461.6220, 276.2340, 180.8940, 412.890…
#> $ gross_margin <dbl> 406.84000, 54.97500, 401.64600, 254.73000, 337.76610, 36…
#> $ unit_margin <dbl> 203.42000, 54.97500, 133.88200, 84.91000, 112.58870, 182…Getting started
contoso gives you the same retail dataset in two ways: as tables bundled with the package, and as larger cloud versions you query through ‘DuckDB’.
Bundled tables
Loading the package makes eight tables available: sales, orders, orderrows, customer, product, store, fx and calendar. They need no download or connection.
Join them on their _key columns:
sales |>
dplyr::left_join(store, by = "store_key") |>
dplyr::summarise(net_revenue = sum(net_revenue), .by = country_name) |>
dplyr::arrange(dplyr::desc(net_revenue))
#> # A tibble: 9 × 2
#> country_name net_revenue
#> <chr> <dbl>
#> 1 Online 3919178.
#> 2 United States 1808404.
#> 3 Germany 431675.
#> 4 Canada 333493.
#> 5 United Kingdom 302591.
#> 6 Australia 221227.
#> 7 Netherlands 129077.
#> 8 France 88228.
#> 9 Italy 72067.Larger datasets in ‘DuckDB’
create_contoso_duckdb() streams the Parquet files from cloud storage into an in-memory ‘DuckDB’ database. Pick a size by the number of sales rows:
size |
sales rows |
|---|---|
"small" |
7,794 |
"medium" |
2,349,091 |
"large" |
23,719,935 |
"mega" |
237,245,485 |
"small" is the same data as the bundled tables. The other sizes cover a different date range and a much larger customer catalogue.
db <- create_contoso_duckdb(size = "medium")The result is a list with one lazy table per dataset and the connection, db$con. Write dplyr as usual; it runs in ‘DuckDB’ until you collect():
db$sales |>
dplyr::summarise(net_revenue = sum(net_revenue), .by = currency_code) |>
dplyr::collect()Use launch_ui() to browse every table in the ‘DuckDB’ UI, and disconnect when you are done:
launch_ui(db$con)
DBI::dbDisconnect(db$con, shutdown = TRUE)Data dictionary
Every table and column is described in a data-dict file, with keys, joins and the formulas behind each measure:
system.file("extdata", "small", "data-dict.yaml", package = "contoso")Use "cloud" in place of "small" for the dictionary of the larger sizes.
Next steps
The package also includes 1,127 fictional business reports about Contoso’s trading from May 2016 to the end of 2025. See The business reports to read them, and Searching the reports with ragnar to search them.