Convert decimals to fractions in R
You can install the released version of fracture from CRAN with:
install.packages("fracture")
or the development version from GitHub with:
# install.packages("remotes")
remotes::install_github("rossellhayes/fracture")
fracture converts decimals into fractions.
fracture(0.5)
#> [1] 1/2
fracture((1:11) / 12)
#> [1] 1/12 1/6 1/4 1/3 5/12 1/2 7/12 2/3 3/4 5/6 11/12
Additional arguments help you get exactly the result you expect:
fracture((1:11) / 12, common_denom = TRUE)
#> [1] 1/12 2/12 3/12 4/12 5/12 6/12 7/12 8/12 9/12 10/12 11/12
fracture(1 / (2:12), base_10 = TRUE)
#> [1] 5/10 3333333/10000000 25/100 2/10
#> [5] 1666667/10000000 1428571/10000000 125/1000 1111111/10000000
#> [9] 1/10 909091/10000000 833333/10000000
fracture(1 / (2:12), base_10 = TRUE, max_denom = 1000)
#> [1] 5/10 333/1000 25/100 2/10 167/1000 143/1000 125/1000 111/1000
#> [9] 1/10 91/1000 83/1000
fracture(1 / (2:12), base_10 = TRUE, common_denom = TRUE, max_denom = 1000)
#> [1] 500/1000 333/1000 250/1000 200/1000 167/1000 143/1000 125/1000 111/1000
#> [9] 100/1000 91/1000 83/1000
fracture((1:9) / 3, mixed = TRUE)
#> [1] 1/3 2/3 1 1 1/3 1 2/3 2 2 1/3 2 2/3 3
For more advanced work, you may prefer to work with a fraction matrix:
frac_mat((1:11) / 12)
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
#> numerator 1 1 1 1 5 1 7 2 3 5 11
#> denominator 12 6 4 3 12 2 12 3 4 6 12
frac_mat()
accepts all the same arguments as fracture()
.
When mixed fractions are used, frac_mat()
has three rows:
frac_mat((1:9) / 3, mixed = TRUE, common_denom = TRUE)
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
#> integer 0 0 1 1 1 2 2 2 3
#> numerator 1 2 0 1 2 0 1 2 0
#> denominator 3 3 3 3 3 3 3 3 3
fracture
s are implemented using an S3 class. This means we can perform
mathematical operations on them like real fractions.
fracture(0.25) * 2
#> [1] 1/2
fracture(0.25) + fracture(1/6)
#> [1] 5/12
frac_style()
uses Unicode to provide stylish formatting for inline
fractions.
`r frac_style(pi, mixed = TRUE, max_denom = 500)`
3 ¹⁶/₁₁₃
Use fracture to find the best approximations of π for each maximum denominator.
unique(purrr::map_chr(1:50000, ~ fracture(pi, max_denom = .x)))
#> [1] "3/1" "22/7" "333/106" "355/113" "103993/33102"
#> [6] "104348/33215"
Isn’t is interesting that there’s such a wide gap between ³⁵⁵/₁₁₃ and ¹⁰³⁹⁹³/₃₃₁₀₂?
fracture is implemented using optimized C++ with
Rcpp and S3 methods. This allows it to run
faster than alternatives like
MASS::fractions()
or
fractional::fractional()
.*
# Performance with a single value
single_benchmark
#> # A tibble: 3 x 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 print(fracture(x[1])) 1 1 2.39 1 1.33
#> 2 print(MASS::fractions(x[1])) 2.14 2.47 1 26.4 1.98
#> 3 print(fractional::fractional(x[1])) 1.55 1.53 1.60 18.3 1
# Performance with a vector of length 1000
vector_benchmark
#> # A tibble: 3 x 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 print(fracture(x)) 1 1 1.78 1 1
#> 2 print(MASS::fractions(x)) 2.18 1.52 1.18 7.24 2.17
#> 3 print(fractional::fractional(x)) 2.77 1.94 1 1.85 2.21
* fractional()
does not compute a decimal’s fractional equivalent
until it is printed. Therefore, benchmarking the time to print provides
a fairer test of the three packages’ capabilities.
Hex sticker fonts are Source Code Pro by Adobe and Hasklig by Ian Tuomi.
Please note that fracture is released with a Contributor Code of Conduct. By contributing to this project, you agree to abide by its terms.