Skip to content
/ ggtedious Public template

a demo package for messages, warnings, errors and test in ggplot2 extension "Testing your code can be painful and tedious, but it greatly increases the quality of your code."

Notifications You must be signed in to change notification settings

EvaMaeRey/ggtedious

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Welcome to the ggtedious workshop!

Let’s build a cool ggplot2 extension function. And then let’s put it in a package. And test! Maybe it will be tedious, but more fun in good company?

‘Testing your code can be painful and tedious, but it greatly increases the quality of your code.’ - testthat introduction (probably Hadley Wickham)

In this workshop, we’ll build and strengthen package building and test writing muscles.

https://angeladuckworth.com/grit-scale/

Meeting objectives:

  1. Practice a compute_group easy geom extension by creating geom_post().
  2. Put them in a package using best practices.
  3. Meet like-minded stats educators, ggplot2 extenders, and package developers.

Prerequisite:

Having written a ‘compute group’ geom extension. See: https://evamaerey.github.io/mytidytuesday/2022-01-03-easy-geom-recipes/easy_geom_recipes.html Seasoned R/ggplot2 users mostly spent ~ 15 minutes on each recipe.

Part 1. Work on functionality

Step 0. Do it with base ggplot2 can become problem statement later

prize_wheel <- data.frame(probs = c(.7, .2, .1), payout = c(0, 1, 5))

library(ggplot2)
ggplot(prize_wheel) + 
  aes(x = payout, y = probs) + 
  geom_point() + 
  aes(xend = payout, yend = 0) + 
  geom_segment()

Step 0.b Write like-to-have code code chunk option eval = F

# would show just line
ggplot(prize_wheel) + 
  aes(x = payout, y = probs) + 
  geom_post()

# line and dot
ggplot(prize_wheel) + 
  aes(x = payout, y = probs) + 
  geom_point() + 
  geom_lollipop()

Step 1. Write compute group function and test

reference: https://evamaerey.github.io/mytidytuesday/2022-01-03-easy-geom-recipes/easy_geom_recipes.html

Step 2. Pass to ggproto object

Step 3. Write geom_post() functions

Step 3.1 Bonus, write geom_lollipop with list mechanism

geom_lollipop <- function(...){

  list(  
  geom_post(...),
  geom_point(...)
  )
  
}

Step 4. Test it out enjoy! (possibly basis of examples and tests)

Step 5. Write messages/warnings etc in the function

Part II. Packaging and documentation 🚧 ✅

Phase 1. Minimal working package

Bit A. Created package archetecture, running devtools::create(".") in interactive session. 🚧 ✅

devtools::create(".")

Bit B. Added roxygen skeleton? 🚧 ✅

Use a roxygen skeleton for auto documentation and making sure proposed functions are exported. Generally, early on, I don’t do much (anything) in terms of filling in the skeleton for documentation, because things may change.

Bit C. Managed dependencies ? 🚧 ✅

Package dependencies managed, i.e. depend::function() in proposed functions and declared in the DESCRIPTION

usethis::use_package("ggplot2")

Bit D. Moved functions R folder? 🚧 ✅

Use new {readme2pkg} function to do this from readme…

library(tidyverse)
readme2pkg::chunk_to_r("geom_post")

Bit E. Run devtools::check() and addressed errors. 🚧 ✅

devtools::check(pkg = ".")

Bit F. Build package 🚧 ✅

devtools::build()

Bit G. Write traditional README that uses built package (also serves as a test of build. 🚧 ✅

The goal of the {ggtedious} package is to make it easy to draw posts (and to learn about package building and testing)

Install package with:

remotes::install_github("EvaMaeRey/ggtedious")

Once functions are exported you can remove go to two colons, and when things are are really finalized, then go without colons (and rearrange your readme…)

library(ggtedious)  

Bit H. Chosen a license? 🚧 ✅

usethis::use_mit_license()

Bit I. Add lifecycle badge (experimental) 🚧 ✅

usethis::use_lifecycle_badge("experimental")

Phase 2: Listen & iterate 🚧 ✅

Try to get feedback from experts on API, implementation, default decisions. Is there already work that solves this problem?

Phase 3: Let things settle

Bit A. Settle on examples. Put them in the roxygen skeleton and readme. 🚧 ✅

Bit B. Written formal tests of functions and save to test that folders 🚧 ✅

That would look like this…

library(testthat)

test_that("calc times 2 works", {
  expect_equal(times_two(4), 8)
  expect_equal(times_two(5), 10)
  
})
readme2pkg::chunk_to_tests_testthat("test_calc_times_two_works")

Bit C. Added a description and author information in the DESCRIPTION file 🚧 ✅

Bit D. Addressed all notes, warnings and errors. 🚧

Phase 4. Promote to wider audience…

Bit A. Package website built? ✅

usethis::use_pkgdown()
pkgdown::build_site()

Bit B. Package website deployed? 🚧 ✅

Phase 5: Harden/commit

Submit to CRAN/RUniverse? 🚧

Appendix: Reports, Environment

Edited Description file?

readLines("DESCRIPTION")

About

a demo package for messages, warnings, errors and test in ggplot2 extension "Testing your code can be painful and tedious, but it greatly increases the quality of your code."

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published