Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can pillar_shaft.POSIXt() respect the digits.secs option? #74

Closed
DavisVaughan opened this issue Jan 5, 2018 · 3 comments · Fixed by #81
Closed

Can pillar_shaft.POSIXt() respect the digits.secs option? #74

DavisVaughan opened this issue Jan 5, 2018 · 3 comments · Fixed by #81

Comments

@DavisVaughan
Copy link
Member

I think it would be nice if pillar_shaft.POSIXt() printed POSIXct objects in the same way as base R, respecting getOption("digits.secs"). This is mainly useful for printing fractional seconds, which aren't currently shown at any time in the current implementation.

The following seems to work well enough for me:

pillar_shaft.POSIXt <- function(x, ...) {
  
  # Get the value of the option, default is 0
  fractional       <- getOption("digits.secs")
  # The width needs to be adjusted. If we are printing fractional seconds, adjust
  # by adding the number of fractional seconds to print +1 for the decimal, otherwise do nothing.
  fractional_width <- ifelse(fractional, fractional + 1, 0)
  
  date <- format(x, format = "%Y-%m-%d")

  # Use the "%OS" format to print. When we don't use any fractional seconds, I believe
  # "%OS0" is equivalent to "%S"
  time <- format(x, format = paste0("%H:%M:%OS", fractional))
  
  datetime <- paste0(date, " " , style_subtle(time))
  datetime[is.na(x)] <- NA
  
  # Add to the width
  new_pillar_shaft_simple(datetime, width = 19 + fractional_width, align = "left")
}

Using this gives:

from <- as.POSIXct("14:03:55", format="%H:%M:%OS",tz="UTC")
to   <- as.POSIXct("14:04:00", format="%H:%M:%OS", tz="UTC")

ex <- tibble::tibble(datetime = seq(from, to, by = 0.01))

ex
#> # A tibble: 501 x 1
#>    datetime           
#>    <dttm>             
#>  1 2018-01-04 14:03:55
#>  2 2018-01-04 14:03:55
#>  3 2018-01-04 14:03:55
#>  4 2018-01-04 14:03:55
#>  5 2018-01-04 14:03:55
#>  6 2018-01-04 14:03:55
#>  7 2018-01-04 14:03:55
#>  8 2018-01-04 14:03:55
#>  9 2018-01-04 14:03:55
#> 10 2018-01-04 14:03:55
#> # ... with 491 more rows

options(digits.secs = 4)

ex
#> # A tibble: 501 x 1
#>    datetime                
#>    <dttm>                  
#>  1 2018-01-04 14:03:55.0000
#>  2 2018-01-04 14:03:55.0099
#>  3 2018-01-04 14:03:55.0199
#>  4 2018-01-04 14:03:55.0299
#>  5 2018-01-04 14:03:55.0399
#>  6 2018-01-04 14:03:55.0499
#>  7 2018-01-04 14:03:55.0599
#>  8 2018-01-04 14:03:55.0699
#>  9 2018-01-04 14:03:55.0799
#> 10 2018-01-04 14:03:55.0899
#> # ... with 491 more rows

The results from using options(digits.secs = 4) are a bit strange, but I think this has been confirmed as the intended output by R core.

krlmlr added a commit that referenced this issue Jan 11, 2018
- Date columns now show sub-seconds if the `digits.secs` option is set (#74).
krlmlr added a commit that referenced this issue Jan 11, 2018
- `NA` values are now shown in plain red, without changing the background color (#70).
- New options to control the output, with defaults that match the current behavior unless stated otherwise:
    - `pillar.sigfig` to control the number of significant digits, for highlighting and truncation (#72),
    - `pillar.subtle` to specify if insignificant digits should be printed in gray (#72),
    - `pillar.neg` to specify if negative digits should be printed in red,
    - `pillar.bold` to specify if column headers should be printed in bold (default: `FALSE`, #76),
    - `pillar.min_title_chars` to specify the minimum number of characters to display for each column name (default: 15 characters, #75).
- Shortened abbreviations for types: complex: cplx -> cpl, function: fun -> fn, factor: fctr -> fct (#71).
- Date columns now show sub-seconds if the `digits.secs` option is set (#74).
- Work around failing CRAN tests on Windows.
@DavisVaughan
Copy link
Member Author

DavisVaughan commented Jan 11, 2018

@krlmlr, thanks for taking a look at this. Do you need to shift the width parameter too?

# with dev pillar and tibble
library(pillar)
library(rlang)

from <- as.POSIXct("14:03:55", format="%H:%M:%OS", tz="UTC")
to   <- as.POSIXct("14:04:00", format="%H:%M:%OS", tz="UTC")

options(digits.secs = 4)

ex <- tibble::tibble(datetime = seq(from, to, by = 0.01))

ex$col <- 100000

ex
#> # A tibble: 501 x 2
#>    datetime               col
#>    <dttm>               <dbl>
#>  1 2018-01-11 14:03:55.0000 100000
#>  2 2018-01-11 14:03:55.0099 100000
#>  3 2018-01-11 14:03:55.0199 100000
#>  4 2018-01-11 14:03:55.0299 100000
#>  5 2018-01-11 14:03:55.0399 100000
#>  6 2018-01-11 14:03:55.0499 100000
#>  7 2018-01-11 14:03:55.0599 100000
#>  8 2018-01-11 14:03:55.0699 100000
#>  9 2018-01-11 14:03:55.0799 100000
#> 10 2018-01-11 14:03:55.0899 100000
#> # ... with 491 more rows

# This should really be for POSIXt and would need the %||% from rlang
pillar_shaft.POSIXct <- function (x, ...) 
{
  width <- 19
  digits.secs <- getOption("digits.secs") %||% 0
  if (digits.secs) {
    width <- width + digits.secs + 1L
  } 
  
  date <- format(x, format = "%Y-%m-%d")
  time <- format(x, format = "%H:%M:%OS")
  datetime <- paste0(date, " ", style_subtle(time))
  datetime[is.na(x)] <- NA
  new_pillar_shaft_simple(datetime, width = width, align = "left")
}

ex
#> # A tibble: 501 x 2
#>    datetime                    col
#>    <dttm>                    <dbl>
#>  1 2018-01-11 14:03:55.0000 100000
#>  2 2018-01-11 14:03:55.0099 100000
#>  3 2018-01-11 14:03:55.0199 100000
#>  4 2018-01-11 14:03:55.0299 100000
#>  5 2018-01-11 14:03:55.0399 100000
#>  6 2018-01-11 14:03:55.0499 100000
#>  7 2018-01-11 14:03:55.0599 100000
#>  8 2018-01-11 14:03:55.0699 100000
#>  9 2018-01-11 14:03:55.0799 100000
#> 10 2018-01-11 14:03:55.0899 100000
#> # ... with 491 more rows

Created on 2018-01-11 by the reprex package (v0.1.1.9000).

Rationale for my solution is that it solves three cases:

  • User hasn't set the option, should default to NULL which is changed to 0
  • User has set the option to 0
  • User has set the option to >0

krlmlr added a commit that referenced this issue Jan 19, 2018
- `NA` values are now shown in plain red, without changing the background color (#70).
- New options to control the output, with defaults that match the current behavior unless stated otherwise:
    - `pillar.sigfig` to control the number of significant digits, for highlighting and truncation (#72),
    - `pillar.subtle` to specify if insignificant digits should be printed in gray (#72),
    - `pillar.neg` to specify if negative digits should be printed in red,
    - `pillar.bold` to specify if column headers should be printed in bold (default: `FALSE`, #76),
    - `pillar.min_title_chars` to specify the minimum number of characters to display for each column name (default: 15 characters, #75).
- Shortened abbreviations for types: complex: cplx -> cpl, function: fun -> fn, factor: fctr -> fct (#71).
- Date columns now show sub-seconds if the `digits.secs` option is set (#74).
- Very wide tibbles now print faster (#85).
@krlmlr
Copy link
Member

krlmlr commented Mar 1, 2018

@DavisVaughan: Would you mind opening a new issue?

@github-actions
Copy link
Contributor

github-actions bot commented Dec 8, 2020

This old thread has been automatically locked. If you think you have found something related to this, please open a new issue and link to this old issue if necessary.

@github-actions github-actions bot locked and limited conversation to collaborators Dec 8, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants