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 · 2 comments

Comments

Projects
None yet
2 participants
@DavisVaughan

DavisVaughan commented Jan 5, 2018

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 krlmlr closed this in #81 Jan 11, 2018

krlmlr added a commit that referenced this issue Jan 11, 2018

use %OS for printing time (#81)
- 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

Merge tag 'v1.0.99.9000'
- `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

This comment has been minimized.

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

Merge tag 'v1.1.0'
- `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

This comment has been minimized.

Member

krlmlr commented Mar 1, 2018

@DavisVaughan: Would you mind opening a new issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment