Coder Social home page Coder Social logo

prettyunits's Introduction

R-CMD-check Codecov test coverage CRAN RStudio mirror downloads

prettyunits

The prettyunits package formats quantities in human readable form.

  • Time intervals: '1337000' -> '15d 11h 23m 20s'.
  • Vague time intervals: '2674000' -> 'about a month ago'.
  • Bytes: '1337' -> '1.34 kB'.
  • Rounding: '99' with 3 significant digits -> '99.0'
  • p-values: '0.00001' -> '<0.0001'.
  • Colors: '#FF0000' -> 'red'.
  • Quantities: '1239437' -> '1.24 M'.

Installation

You can install the package from CRAN:

install.packages("prettyunits")

Bytes

pretty_bytes formats number of bytes in a human readable way:

pretty_bytes(1337)
##> [1] "1.34 kB"
pretty_bytes(133337)
##> [1] "133.34 kB"
pretty_bytes(13333337)
##> [1] "13.33 MB"
pretty_bytes(1333333337)
##> [1] "1.33 GB"
pretty_bytes(133333333337)
##> [1] "133.33 GB"

Here is a simple function that emulates the Unix ls command, with nicely formatted file sizes:

uls <- function(path = ".") {
  files <- dir(path)
  info <- files %>%
    lapply(file.info) %>%
    do.call(what = rbind)
  info$size <- pretty_bytes(info$size)
  df <- data.frame(d = ifelse(info$isdir, "d", " "),
	mode = as.character(info$mode), user = info$uname, group = info$grname,
    size = ifelse(info$isdir, "", info$size), modified = info$mtime, name = files)
  print(df, row.names = FALSE)
}
uls()
##>  d mode        user group    size            modified        name
##>     644 gaborcsardi staff   232 B 2023-09-24 10:37:41 codecov.yml
##>  d  755 gaborcsardi staff         2023-09-24 10:37:41    data-raw
##>     644 gaborcsardi staff 1.06 kB 2023-09-24 10:40:32 DESCRIPTION
##>     644 gaborcsardi staff    42 B 2022-06-17 13:59:46     LICENSE
##>     644 gaborcsardi staff   111 B 2023-09-23 16:44:21    Makefile
##>  d  755 gaborcsardi staff         2023-09-24 10:37:59         man
##>     644 gaborcsardi staff   523 B 2023-09-24 10:39:58   NAMESPACE
##>     644 gaborcsardi staff 1.46 kB 2023-09-24 10:42:01     NEWS.md
##>  d  755 gaborcsardi staff         2023-09-24 11:25:00           R
##>     644 gaborcsardi staff 7.90 kB 2023-09-24 11:27:42   README.md
##>     644 gaborcsardi staff 4.31 kB 2023-09-24 11:28:23  README.Rmd
##>  d  755 gaborcsardi staff         2022-06-17 13:59:46       tests

Quantities

pretty_num formats number related to linear quantities in a human readable way:

pretty_num(1337)
##> [1] "1.34 k"
pretty_num(-133337)
##> [1] "-133.34 k"
pretty_num(1333.37e-9)
##> [1] "1.33 u"

Be aware that the result is wrong in case of surface or volumes, and for any non-linear quantity.

Here is a simple example of how to prettify a entire tibble

library(tidyverse)
##> ── Attaching core tidyverse packages ─────────────────────────────────────────────────────────────────────────── tidyverse 2.0.0 ──
##> ✔ dplyr     1.1.2     ✔ readr     2.1.4
##> ✔ forcats   1.0.0     ✔ stringr   1.5.0
##> ✔ ggplot2   3.4.2     ✔ tibble    3.2.1
##> ✔ lubridate 1.9.2     ✔ tidyr     1.3.0
##> ✔ purrr     1.0.1     
##> ── Conflicts ───────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
##> ✖ tidyr::extract()   masks magrittr::extract()
##> ✖ dplyr::filter()    masks stats::filter()
##> ✖ dplyr::lag()       masks stats::lag()
##> ✖ purrr::set_names() masks magrittr::set_names()
##> ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
tdf <- tribble( ~name, ~`size in m`, ~`speed in m/s`,
                "land snail", 0.075, 0.001,
                "photon", NA,  299792458,
                "African plate", 10546330, 0.000000000681)
tdf %>% mutate(across(where(is.numeric), pretty_num))
##> # A tibble: 3 × 3
##>   name          `size in m` `speed in m/s`
##>   <chr>         <chr>       <chr>         
##> 1 land snail    "   75 m"   "     1 m"    
##> 2 photon        "    NA "   "299.79 M"    
##> 3 African plate "10.55 M"   "   681 p"

Time intervals

pretty_ms formats a time interval given in milliseconds. pretty_sec does the same for seconds, and pretty_dt for difftime objects. The optional compact argument turns on a compact, approximate format.

pretty_ms(c(1337, 13370, 133700, 1337000, 1337000000))
##> [1] "1.3s"            "13.4s"           "2m 13.7s"        "22m 17s"        
##> [5] "15d 11h 23m 20s"
pretty_ms(c(1337, 13370, 133700, 1337000, 1337000000),
  compact = TRUE)
##> [1] "~1.3s"  "~13.4s" "~2m"    "~22m"   "~15d"
pretty_sec(c(1337, 13370, 133700, 1337000, 13370000))
##> [1] "22m 17s"          "3h 42m 50s"       "1d 13h 8m 20s"    "15d 11h 23m 20s" 
##> [5] "154d 17h 53m 20s"
pretty_sec(c(1337, 13370, 133700, 1337000, 13370000),
  compact = TRUE)
##> [1] "~22m"  "~3h"   "~1d"   "~15d"  "~154d"

Vague time intervals

vague_dt and time_ago formats time intervals using a vague format, omitting smaller units. They both have three formats: default, short and terse. vague_dt takes a difftime object, and time_ago works relatively to the specified date.

vague_dt(format = "short", as.difftime(30, units = "secs"))
##> [1] "<1 min"
vague_dt(format = "short", as.difftime(14, units = "mins"))
##> [1] "14 min"
vague_dt(format = "short", as.difftime(5, units = "hours"))
##> [1] "5 hours"
vague_dt(format = "short", as.difftime(25, units = "hours"))
##> [1] "1 day"
vague_dt(format = "short", as.difftime(5, units = "days"))
##> [1] "5 day"
now <- Sys.time()
time_ago(now)
##> [1] "moments ago"
time_ago(now - as.difftime(30, units = "secs"))
##> [1] "less than a minute ago"
time_ago(now - as.difftime(14, units = "mins"))
##> [1] "14 minutes ago"
time_ago(now - as.difftime(5, units = "hours"))
##> [1] "5 hours ago"
time_ago(now - as.difftime(25, units = "hours"))
##> [1] "a day ago"

Rounding

pretty_round() and pretty_signif() preserve trailing zeros.

pretty_round(1, digits=6)
##> [1] "1.000000"
pretty_signif(c(99, 0.9999), digits=3)
##> [1] "99.0" "1.00"

p-values

pretty_p_value() rounds small p-values to indicate less than significance level for small values.

pretty_p_value(c(0.05, 0.0000001, NA))
##> [1] "0.0500"  "<0.0001" NA

Colors

pretty_color converts colors from other representations to human-readable names.

pretty_color("black")
##> [1] "black"
##> attr(,"alt")
##> [1] "black" "gray0" "grey0" "Black"
pretty_color("#123456")
##> [1] "Prussian Blue"
##> attr(,"alt")
##> [1] "Prussian Blue"

prettyunits's People

Contributors

billdenney avatar cregouby avatar gaborcsardi avatar mllg avatar petermeissner avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

prettyunits's Issues

Feature Request: Color Naming

I recently found myself wanting a way to convert a color to a human-readable name (to automate making captions for figures in reports).

I'd think that this would be implemented as follows:

  • Take the color names from colors().
  • Clean them up to be more human readable (e.g. convert all the items like "aquamarine4" to "dark aquamarine" and add some spaces to items like "blanched almond"), and
    • This would be the "full color list".
  • Simplify the full color list to a shorter selection of a smaller number of colors (how different is "azure3" from "gray" or "wheat3" compared to "tan", really?), and
    • This would be the "simple color list".

For any input color, find the nearest color name (using one of the algorithms here: https://en.wikipedia.org/wiki/Color_difference) and return that to the user. The user could optionally choose either the "simple" or "full" color list (defaulting to simple).

Release 1.1.0

Prepare for release:

  • devtools::check_win_devel()
  • rhub::check_for_cran()
  • revdepcheck::revdep_check(num_workers = 4)
  • Polish NEWS
  • If new failures, update email.yml then revdepcheck::revdep_email_maintainers()

Perform release:

  • Bump version (in DESCRIPTION and NEWS)
  • Submit to CRAN
  • Approve email

Wait for CRAN...

  • Tag release
  • Bump dev version
  • Write blog post
  • Tweet

Awkward formatting with pretty_bytes()

prettyunits::pretty_bytes(2**(1:20))
#>  [1] "  2.000000 B" "  4.000000 B" "  8.000000 B" " 16.000000 B" " 32.000000 B"
#>  [6] " 64.000000 B" "128.000000 B" "256.000000 B" "512.000000 B" "     1.02 kB"
#> [11] "     2.05 kB" "     4.10 kB" "     8.19 kB" "    16.38 kB" "    32.77 kB"
#> [16] "    65.54 kB" "   131.07 kB" "   262.14 kB" "   524.29 kB" "     1.05 MB"

Created on 2020-01-15 by the reprex package (v0.3.0)

Seen and used in {blob}.

pretty_dt breaks in case of "Time difference of NA secs"

Consider the following example below.

While difftime() considers it valid to have NA time differences, pretty_dt() does break with a rather ominous error message.

  • It would be great to have pretty_dt() just return "NA" and not error out.
  • If this is not possible it would be great to have at least a more informative error message that hints at where and why the problem is occurring (e.g. "pretty_dt: Sorry, do not know how to handle NA difftimes.")
difftime(NA,NA)
## Time difference of NA secs

pretty_dt(difftime(NA,NA))
## Error in if (pieces[1]) pieces[1] %+% "d " else "" : 
##   argument is not interpretable as logical

Move `master` branch to `main`

The master branch of this repository will soon be renamed to main, as part of a coordinated change across several GitHub organizations (including, but not limited to: tidyverse, r-lib, tidymodels, and sol-eng). We anticipate this will happen by the end of September 2021.

That will be preceded by a release of the usethis package, which will gain some functionality around detecting and adapting to a renamed default branch. There will also be a blog post at the time of this master --> main change.

The purpose of this issue is to:

  • Help us firm up the list of targetted repositories
  • Make sure all maintainers are aware of what's coming
  • Give us an issue to close when the job is done
  • Give us a place to put advice for collaborators re: how to adapt

message id: euphoric_snowdog

Release prettyunits 1.2.0

Prepare for release:

  • git pull
  • Check current CRAN check results
  • Polish NEWS
  • usethis::use_github_links()
  • urlchecker::url_check()
  • devtools::build_readme()
  • devtools::check(remote = TRUE, manual = TRUE)
  • devtools::check_win_devel()
  • revdepcheck::revdep_check(num_workers = 8)
  • Update cran-comments.md
  • git push
  • Draft blog post

Submit to CRAN:

  • usethis::use_version('minor')
  • devtools::submit_cran()
  • Approve email

Wait for CRAN...

  • Accepted 🎉
  • Add preemptive link to blog post in pkgdown news menu
  • usethis::use_github_release()
  • usethis::use_dev_version(push = TRUE)
  • Finish blog post
  • Tweet

Feature Request: p-value prettification

I often need to present p-values where small values are shown with a representation like "<0.001". Would you be interested in me converting the code below into a pull request?

#' p-values in a human-readable string
#'
#' @param x A numeric vector
#' @param minval The minimum p-value to show (lower values will show as
#'   `paste0("<", minval)`)
#' @return A character vector of p-value representations
#' @export
#' @importFrom PKNCA roundString
pretty_p_value <- function(x, minval=0.0001) {
  ndigits <- -floor(log10(minval))
  mask_min <- !is.na(x) & x < minval
  mask_over <- !is.na(x) & x >= minval
  ret <- rep(NA_character_, length(x))
  ret[mask_min] <- paste0("<", PKNCA::roundString(minval, digits=ndigits))
  ret[mask_over] <- PKNCA::roundString(x[mask_over], digits=ndigits)
  ret
}

S3 Classes with format and print?

For instance:

dput(pretty_bytes(1000))
> structure(1000, class = "pretty_bytes")
print(pretty_bytes(1000))
> [1] "1 kB"

Would you support this kind of functionality? It might break compatibility, but then there are not many revdeps (yet) ;-)

Add support for monetary amounts.

I often have to render monetary amounts in tables that span multiple orders of magnitude. It would be nice if there were a way to 'pretty print' these sanely, so e.g. 1357 would render as "$1.36 K", 5.5e7 renders as "$55 M", and so on. I've written one-off code that does it, but would prefer it live in some canonical package, like this one.

add functionality for big numbers

Would you consider to add some functionality to prettyunits
like mentioned here https://bugs.r-project.org/bugzilla/show_bug.cgi?id=16982

#Abbreviate some big numbers using a suffix "k", "M":
abbreviate_num <- function (i) {
    n <- floor(log(i, 1000))
    n <- ifelse(n>2, 2, n)
    paste0(round(i/(1000^n), 2), c("", "k", "M")[n+1])
}
abbreviate_num(222)
[1] "222"
abbreviate_num(1422)
[1] "1.42k"
abbreviate_num(14223)
[1] "14.22k"
abbreviate_num(14223323)
[1] "14.22M"

Release version 1.1.1

Prepare for release:

  • devtools::check_win_devel() slow today...
  • rhub::check_for_cran()
  • revdepcheck::revdep_check(num_workers = 4)
  • Polish NEWS
  • If new failures, update email.yml then revdepcheck::revdep_email_maintainers()

Perform release:

  • Bump version (in DESCRIPTION and NEWS)
  • Submit to CRAN
  • Approve email

Wait for CRAN...

  • Tag release
  • Bump dev version
  • Write blog post
  • Tweet

Feature Request: Numeric Value Rounding and Signif to Strings

A limitation of results from the signif() or round() functions is that trailing zeros may be lost. As used in #13, I have implemented functions roundString() and signifString() in my PKNCA package, but the package isn't a good fit for the functions since they are simply for making numbers into prettier strings (which has nothing to do with the purpose of the package around calculations for the kinetics of medicines in people or animals).

Would you be interested in a PR that would make something like pretty_round() and pretty_signif() functions that would give the character representation with the requested number of digits maintained?

Feature request: Provide option to convert bytes on 2 or 10 base

As we all know this:

Notation      Symbol    Value
1 kilobyte    1 kB      10^3  = 1000 bytes
1 megabyte    1 MB      10^6  = 1000000 bytes
1 gigabyte    1 GB      10^9  = 1000000000 bytes
1 terabyte    1 TB      10^12 = 1000000000000 bytes


1 kibibyte    1 KiB     2^10 = 1024 bytes
1 mebibyte    1 MiB     2^20 = 1048576 bytes
1 gibibyte    1 GiB     2^30 = 1073741824 bytes
1 tebibyte    1 TiB     2^40 = 1099511627776 bytes

it still creates often confusion when dealing with size related metrics within IT world.

The prettyunits library should offer an option to use either 2 base or 10 base for its bytes conversion. The default (10 base) can stay as it is for providing backward compatibility, although a clear statement regarding this is missing in the documentation.

...prettyunits.rdb' is corrupt

I am not sure if this is a problem with "prettyunits" or "bartMan".

I attempted to install the bartMan package using devtools. It proceeded to install prettyunits, but then threw the following error.

I tried manually installing prettyunits (new and old version from tar.gz) and got the same error

"Lazy-load database 'C:/Users/mschwartz/AppData/Local/R/win-library/4.2/prettyunits/R/prettyunits.rdb' is corrupt"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.