An implementation of an S3 class based on a double vector for storing and displaying precision teaching measures, representing a growing or a decaying (multiplicative) change between two frequencies. The main format method allows researchers to display measures (including data.frame) that respect the established conventions in the precision teaching community (i.e., prefixed multiplication or division symbol, displayed number <= 1). Basic multiplication and division methods are allowed and other useful functions are provided for creating, converting or inverting precision teaching measures. For more details, see Pennypacker, Gutierrez and Lindsley (2003, ISBN: 1-881317-13-7).
The goal of ptvalue is to provide a S3 class for printing and for small manipulation of Precision Teaching (PT) values (ex., values of celeration, bounce) inside a vector or a dataframe. These values, are usually written on a Standard Celeration Chart (Calkin, 2005; Pennypacker et al., 2003), can be used for further calculations and to print a nice table for report or paper. Some basic helper functions directly related to the manipulation of PT values are also provided.
As this package is could be imported inside other packages (ex., ptchart), it will stay small and simple. The dependency from other packages will also be kept minimal.
You can install ptvalue with the following code:
install.packages("ptvalue")
Or you can install the development version as follow:
remotes::install_github("agkamel/ptvalue")
You can create PT values with ptvalue():
library(ptvalue)
ptvalue(c(0.5, 1.4, 2))
#> <ptvalue[3]>
#> [1] ÷2 ×1.4 ×2
For all original values that are greater or equal than $1$, a prefixed $\times$ symbol is added. For all original values that are greater than $0$ and smaller than $1$, these values are also converted to values greater than $1$, but a prefixed $\div$ symbol is added:
ptvalue(c(5, 2, 1.25))
#> <ptvalue[3]>
#> [1] ×5 ×2 ×1.2
ptvalue(c(0.2, 0.5, 0.8))
#> <ptvalue[3]>
#> [1] ÷5 ÷2 ÷1.2
Negative values always raises an error.
ptvalue(-1) # Raises an error
PT values created with ptvalue() can be stored in objects:
x <- ptvalue(c(0.5, 1.4, 2))
x
#> <ptvalue[3]>
#> [1] ÷2 ×1.4 ×2
…and be inserted in dataframe as well:
pt_df <- tibble::tibble(
phase = 1:3,
celeration = x)
pt_df
#> # A tibble: 3 × 2
#> phase celeration
#> <int> <ptval>
#> 1 1 ÷2
#> 2 2 ×1.4
#> 3 3 ×2
The type of a ptvalue vector is double. The original values are
always conserved under the hood, it is only the printing that is
different. These can always be converted back:
unclass(x)
#> [1] 0.5 1.4 2.0
as.double(x)
#> [1] 0.5 1.4 2.0
Finaly, PT values can be created with times() or div(). In
particular, the function div() is convenient for creating decaying PT
values without having to find the decimal format before. These following
three examples return the same PT values:
ptvalue(c(0.5, 0.25, 0.125, 0.0625))
#> <ptvalue[4]>
#> [1] ÷2 ÷4 ÷8 ÷16
ptvalue(c(1/2, 1/4, 1/8, 1/16))
#> <ptvalue[4]>
#> [1] ÷2 ÷4 ÷8 ÷16
div(c(2, 4, 8, 16))
#> <ptvalue[4]>
#> [1] ÷2 ÷4 ÷8 ÷16
Because original values are always conserved, this allows us to multiply PT values:
# Multiplication is commutative
ptvalue(x) * ptvalue(2)
#> <ptvalue[3]>
#> [1] ×1 ×2.8 ×4
ptvalue(2) * ptvalue(x)
#> <ptvalue[3]>
#> [1] ×1 ×2.8 ×4
… and divide PT values:
# Division is not commutative
ptvalue(x) / ptvalue(2)
#> <ptvalue[3]>
#> [1] ÷4 ÷1.4 ×1
ptvalue(2) / ptvalue(x)
#> <ptvalue[3]>
#> [1] ×4 ×1.4 ×1
PT values can be multipled by a numeric values…
ptvalue(x) * 2
#> <ptvalue[3]>
#> [1] ×1 ×2.8 ×4
…or divided:
# Division is not commutative
ptvalue(x) / 2
#> <ptvalue[3]>
#> [1] ÷4 ÷1.4 ×1
2 / ptvalue(x)
#> <ptvalue[3]>
#> [1] ×4 ×1.4 ×1
PT values can be used with comparison operators as well:
x < ptvalue(1.8)
#> [1] TRUE TRUE FALSE
x == ptvalue(1.4)
#> [1] FALSE TRUE FALSE
You can invert signs of PT values with invert_sign():
x
#> <ptvalue[3]>
#> [1] ÷2 ×1.4 ×2
invert_sign(x)
#> <ptvalue[3]>
#> [1] ×2 ÷1.4 ÷2
You can convert values to absolute multiplicative values with
abs_sign() (times or div):
abs_sign(x)
#> <ptvalue[3]>
#> [1] ×2 ×1.4 ×2
abs_sign(x, sign = "div")
#> <ptvalue[3]>
#> [1] ÷2 ÷1.4 ÷2
Alternatively, as_times() and as_div() are wrappers of abs_sign():
as_times(x)
#> <ptvalue[3]>
#> [1] ×2 ×1.4 ×2
as_div(x)
#> <ptvalue[3]>
#> [1] ÷2 ÷1.4 ÷2
Because PT values can be stored in dataframes, it helps us to generate beautiful tables for journal articles or for reports.
pt_df |>
knitr::kable(col.names = c("Phase", "Celeration"))
| Phase | Celeration |
|---|---|
| 1 | ÷2 |
| 2 | ×1.4 |
| 3 | ×2 |