greta-dev / greta

simple and scalable statistical modelling in R
https://greta-stats.org
Other
527 stars 63 forks source link

Change default print method of greta arrays to be shorter #480

Closed njtierney closed 2 months ago

njtierney commented 2 years ago

Currently, if you have a long or wide greta array, the printing method takes up the whole console.

It would be great if we could work out a way to print the greta array objects so they don't clutter the whole console. Similar to the print method with data.table, which shows the head and tail, or how tibble has made the default printing 10 rows.

library(greta)
#> 
#> Attaching package: 'greta'
#> The following objects are masked from 'package:stats':
#> 
#>     binomial, cov2cor, poisson
#> The following objects are masked from 'package:base':
#> 
#>     %*%, apply, backsolve, beta, chol2inv, colMeans, colSums, diag,
#>     eigen, forwardsolve, gamma, identity, rowMeans, rowSums, sweep,
#>     tapply

long <- as_data(seq(from = 0, to = 1, length = 100))
#> ℹ Initialising python and checking dependencies, this may take a moment.
#> ✓ Initialising python and checking dependencies ... done!
#> 
long
#> greta array (data)
#> 
#>              [,1]
#>   [1,] 0.00000000
#>   [2,] 0.01010101
#>   [3,] 0.02020202
#>   [4,] 0.03030303
#>   [5,] 0.04040404
#>   [6,] 0.05050505
#>   [7,] 0.06060606
#>   [8,] 0.07070707
#>   [9,] 0.08080808
#>  [10,] 0.09090909
#>  [11,] 0.10101010
#>  [12,] 0.11111111
#>  [13,] 0.12121212
#>  [14,] 0.13131313
#>  [15,] 0.14141414
#>  [16,] 0.15151515
#>  [17,] 0.16161616
#>  [18,] 0.17171717
#>  [19,] 0.18181818
#>  [20,] 0.19191919
#>  [21,] 0.20202020
#>  [22,] 0.21212121
#>  [23,] 0.22222222
#>  [24,] 0.23232323
#>  [25,] 0.24242424
#>  [26,] 0.25252525
#>  [27,] 0.26262626
#>  [28,] 0.27272727
#>  [29,] 0.28282828
#>  [30,] 0.29292929
#>  [31,] 0.30303030
#>  [32,] 0.31313131
#>  [33,] 0.32323232
#>  [34,] 0.33333333
#>  [35,] 0.34343434
#>  [36,] 0.35353535
#>  [37,] 0.36363636
#>  [38,] 0.37373737
#>  [39,] 0.38383838
#>  [40,] 0.39393939
#>  [41,] 0.40404040
#>  [42,] 0.41414141
#>  [43,] 0.42424242
#>  [44,] 0.43434343
#>  [45,] 0.44444444
#>  [46,] 0.45454545
#>  [47,] 0.46464646
#>  [48,] 0.47474747
#>  [49,] 0.48484848
#>  [50,] 0.49494949
#>  [51,] 0.50505051
#>  [52,] 0.51515152
#>  [53,] 0.52525253
#>  [54,] 0.53535354
#>  [55,] 0.54545455
#>  [56,] 0.55555556
#>  [57,] 0.56565657
#>  [58,] 0.57575758
#>  [59,] 0.58585859
#>  [60,] 0.59595960
#>  [61,] 0.60606061
#>  [62,] 0.61616162
#>  [63,] 0.62626263
#>  [64,] 0.63636364
#>  [65,] 0.64646465
#>  [66,] 0.65656566
#>  [67,] 0.66666667
#>  [68,] 0.67676768
#>  [69,] 0.68686869
#>  [70,] 0.69696970
#>  [71,] 0.70707071
#>  [72,] 0.71717172
#>  [73,] 0.72727273
#>  [74,] 0.73737374
#>  [75,] 0.74747475
#>  [76,] 0.75757576
#>  [77,] 0.76767677
#>  [78,] 0.77777778
#>  [79,] 0.78787879
#>  [80,] 0.79797980
#>  [81,] 0.80808081
#>  [82,] 0.81818182
#>  [83,] 0.82828283
#>  [84,] 0.83838384
#>  [85,] 0.84848485
#>  [86,] 0.85858586
#>  [87,] 0.86868687
#>  [88,] 0.87878788
#>  [89,] 0.88888889
#>  [90,] 0.89898990
#>  [91,] 0.90909091
#>  [92,] 0.91919192
#>  [93,] 0.92929293
#>  [94,] 0.93939394
#>  [95,] 0.94949495
#>  [96,] 0.95959596
#>  [97,] 0.96969697
#>  [98,] 0.97979798
#>  [99,] 0.98989899
#> [100,] 1.00000000

wide <- as_data(matrix(1:100, nrow = 1, ncol = 100))
wide
#> greta array (data)
#> 
#>      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
#> [1,]    1    2    3    4    5    6    7    8    9    10    11    12    13    14
#>      [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24] [,25] [,26]
#> [1,]    15    16    17    18    19    20    21    22    23    24    25    26
#>      [,27] [,28] [,29] [,30] [,31] [,32] [,33] [,34] [,35] [,36] [,37] [,38]
#> [1,]    27    28    29    30    31    32    33    34    35    36    37    38
#>      [,39] [,40] [,41] [,42] [,43] [,44] [,45] [,46] [,47] [,48] [,49] [,50]
#> [1,]    39    40    41    42    43    44    45    46    47    48    49    50
#>      [,51] [,52] [,53] [,54] [,55] [,56] [,57] [,58] [,59] [,60] [,61] [,62]
#> [1,]    51    52    53    54    55    56    57    58    59    60    61    62
#>      [,63] [,64] [,65] [,66] [,67] [,68] [,69] [,70] [,71] [,72] [,73] [,74]
#> [1,]    63    64    65    66    67    68    69    70    71    72    73    74
#>      [,75] [,76] [,77] [,78] [,79] [,80] [,81] [,82] [,83] [,84] [,85] [,86]
#> [1,]    75    76    77    78    79    80    81    82    83    84    85    86
#>      [,87] [,88] [,89] [,90] [,91] [,92] [,93] [,94] [,95] [,96] [,97] [,98]
#> [1,]    87    88    89    90    91    92    93    94    95    96    97    98
#>      [,99] [,100]
#> [1,]    99    100

Created on 2022-01-14 by the reprex package (v2.0.1)

Session info ``` r sessioninfo::session_info() #> ─ Session info ─────────────────────────────────────────────────────────────── #> setting value #> version R version 4.1.2 (2021-11-01) #> os macOS Big Sur 10.16 #> system x86_64, darwin17.0 #> ui X11 #> language (EN) #> collate en_AU.UTF-8 #> ctype en_AU.UTF-8 #> tz Australia/Brisbane #> date 2022-01-14 #> pandoc 2.14.0.3 @ /Applications/RStudio.app/Contents/MacOS/pandoc/ (via rmarkdown) #> #> ─ Packages ─────────────────────────────────────────────────────────────────── #> package * version date (UTC) lib source #> backports 1.4.0 2021-11-23 [1] CRAN (R 4.1.0) #> base64enc 0.1-3 2015-07-28 [1] CRAN (R 4.1.0) #> callr 3.7.0 2021-04-20 [1] CRAN (R 4.1.0) #> cli 3.1.0 2021-10-27 [1] CRAN (R 4.1.1) #> coda 0.19-4 2020-09-30 [1] CRAN (R 4.1.0) #> codetools 0.2-18 2020-11-04 [1] CRAN (R 4.1.2) #> crayon 1.4.2 2021-10-29 [1] CRAN (R 4.1.0) #> digest 0.6.29 2021-12-01 [1] CRAN (R 4.1.0) #> ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.1.0) #> evaluate 0.14 2019-05-28 [1] CRAN (R 4.1.0) #> fansi 1.0.0 2022-01-10 [1] CRAN (R 4.1.2) #> fastmap 1.1.0 2021-01-25 [1] CRAN (R 4.1.0) #> fs 1.5.2 2021-12-08 [1] CRAN (R 4.1.0) #> future 1.23.0 2021-10-31 [1] CRAN (R 4.1.0) #> globals 0.14.0 2020-11-22 [1] CRAN (R 4.1.0) #> glue 1.6.0 2021-12-17 [1] CRAN (R 4.1.0) #> greta * 0.4.0 2021-12-21 [1] local #> here 1.0.1 2020-12-13 [1] CRAN (R 4.1.0) #> highr 0.9 2021-04-16 [1] CRAN (R 4.1.0) #> hms 1.1.1 2021-09-26 [1] CRAN (R 4.1.0) #> htmltools 0.5.2 2021-08-25 [1] CRAN (R 4.1.0) #> jsonlite 1.7.2 2020-12-09 [1] CRAN (R 4.1.0) #> knitr 1.37 2021-12-16 [1] CRAN (R 4.1.0) #> lattice 0.20-45 2021-09-22 [1] CRAN (R 4.1.2) #> lifecycle 1.0.1 2021-09-24 [1] CRAN (R 4.1.0) #> listenv 0.8.0 2019-12-05 [1] CRAN (R 4.1.0) #> magrittr 2.0.1 2020-11-17 [1] CRAN (R 4.1.0) #> Matrix 1.3-4 2021-06-01 [1] CRAN (R 4.1.2) #> parallelly 1.29.0 2021-11-21 [1] CRAN (R 4.1.0) #> pillar 1.6.4 2021-10-18 [1] CRAN (R 4.1.0) #> pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.1.0) #> png 0.1-7 2013-12-03 [1] CRAN (R 4.1.0) #> prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.1.0) #> processx 3.5.2 2021-04-30 [1] CRAN (R 4.1.0) #> progress 1.2.2 2019-05-16 [1] CRAN (R 4.1.0) #> ps 1.6.0 2021-02-28 [1] CRAN (R 4.1.0) #> purrr 0.3.4 2020-04-17 [1] CRAN (R 4.1.0) #> R.cache 0.15.0 2021-04-30 [1] CRAN (R 4.1.0) #> R.methodsS3 1.8.1 2020-08-26 [1] CRAN (R 4.1.0) #> R.oo 1.24.0 2020-08-26 [1] CRAN (R 4.1.0) #> R.utils 2.11.0 2021-09-26 [1] CRAN (R 4.1.0) #> R6 2.5.1 2021-08-19 [1] CRAN (R 4.1.0) #> Rcpp 1.0.7 2021-07-07 [1] CRAN (R 4.1.0) #> reprex 2.0.1 2021-08-05 [1] CRAN (R 4.1.0) #> reticulate 1.22 2021-09-17 [1] CRAN (R 4.1.0) #> rlang 0.4.12 2021-10-18 [1] CRAN (R 4.1.0) #> rmarkdown 2.11 2021-09-14 [1] CRAN (R 4.1.0) #> rprojroot 2.0.2 2020-11-15 [1] CRAN (R 4.1.0) #> rstudioapi 0.13 2020-11-12 [1] CRAN (R 4.1.0) #> sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.1.1) #> stringi 1.7.6 2021-11-29 [1] CRAN (R 4.1.0) #> stringr 1.4.0 2019-02-10 [1] CRAN (R 4.1.0) #> styler 1.6.2 2021-09-23 [1] CRAN (R 4.1.0) #> tensorflow 2.7.0 2021-11-09 [1] CRAN (R 4.1.0) #> tfruns 1.5.0 2021-02-26 [1] CRAN (R 4.1.0) #> tibble 3.1.6 2021-11-07 [1] CRAN (R 4.1.0) #> utf8 1.2.2 2021-07-24 [1] CRAN (R 4.1.0) #> vctrs 0.3.8 2021-04-29 [1] CRAN (R 4.1.0) #> whisker 0.4 2019-08-28 [1] CRAN (R 4.1.0) #> withr 2.4.3 2021-11-30 [1] CRAN (R 4.1.0) #> xfun 0.29 2021-12-14 [1] CRAN (R 4.1.0) #> yaml 2.2.1 2020-02-01 [1] CRAN (R 4.1.0) #> #> [1] /Library/Frameworks/R.framework/Versions/4.1/Resources/library #> #> ─ Python configuration ─────────────────────────────────────────────────────── #> python: /Users/njtierney/Library/r-miniconda/envs/greta-env/bin/python #> libpython: /Users/njtierney/Library/r-miniconda/envs/greta-env/lib/libpython3.7m.dylib #> pythonhome: /Users/njtierney/Library/r-miniconda/envs/greta-env:/Users/njtierney/Library/r-miniconda/envs/greta-env #> version: 3.7.12 | packaged by conda-forge | (default, Oct 26 2021, 05:59:23) [Clang 11.1.0 ] #> numpy: /Users/njtierney/Library/r-miniconda/envs/greta-env/lib/python3.7/site-packages/numpy #> numpy_version: 1.16.4 #> tensorflow: /Users/njtierney/Library/r-miniconda/envs/greta-env/lib/python3.7/site-packages/tensorflow #> #> NOTE: Python version was forced by use_python function #> #> ────────────────────────────────────────────────────────────────────────────── ```

It would also be neat to add the dimensions to the print method.

So the long and wide examples above might read as:

greta array (data): 1 x 100

            [,1]
 [1,] 0.00000000
 [2,] 0.01010101
 [3,] 0.02020202
 [4,] 0.03030303
 [5,] 0.04040404
 [6,] 0.05050505
 [7,] 0.06060606
 [8,] 0.07070707
 [9,] 0.08080808
[10,] 0.09090909
# … with 90 more rows
[100,] 1
greta array (data): 100 x 1

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] ... [, 100]
[1,]    1    2    3    4    5    6    7    8    9    10 ...     100
# … with 90 more columns

why?

Because the print methods sometimes take up the whole console, and sometimes that can be a bit annoying as we might lose other things in the console, or we might lose sight of what the structure of the data is in the first place. Additionally, this would also apply to greta arrays, which normally have ? as their contents, and we don't necessarily need to see 100 ? to understand it is 100 long or wide, etc.

related issues

333 and #262

njtierney commented 4 months ago

Another round:

library(greta)
#> 
#> Attaching package: 'greta'
#> The following objects are masked from 'package:stats':
#> 
#>     binomial, cov2cor, poisson
#> The following objects are masked from 'package:base':
#> 
#>     %*%, apply, backsolve, beta, chol2inv, colMeans, colSums, diag,
#>     eigen, forwardsolve, gamma, identity, rowMeans, rowSums, sweep,
#>     tapply

beta <- normal(0,1)
#> ℹ Initialising python and checking dependencies, this may take a moment.
#> ✔ Initialising python and checking dependencies ... done!
#> 
alpha <- normal(0, 1, truncation = c(0, Inf))

m <- model(alpha, beta)

draws <- mcmc(m)
#> running 4 chains simultaneously on up to 8 CPU cores
#> 
#>     warmup                                           0/1000 | eta:  ?s              warmup ==                                       50/1000 | eta: 12s              warmup ====                                    100/1000 | eta:  7s              warmup ======                                  150/1000 | eta:  5s              warmup ========                                200/1000 | eta:  4s              warmup ==========                              250/1000 | eta:  3s              warmup ===========                             300/1000 | eta:  3s              warmup =============                           350/1000 | eta:  2s              warmup ===============                         400/1000 | eta:  2s              warmup =================                       450/1000 | eta:  2s              warmup ===================                     500/1000 | eta:  2s              warmup =====================                   550/1000 | eta:  1s              warmup =======================                 600/1000 | eta:  1s              warmup =========================               650/1000 | eta:  1s              warmup ===========================             700/1000 | eta:  1s              warmup ============================            750/1000 | eta:  1s              warmup ==============================          800/1000 | eta:  1s              warmup ================================        850/1000 | eta:  0s              warmup ==================================      900/1000 | eta:  0s              warmup ====================================    950/1000 | eta:  0s              warmup ====================================== 1000/1000 | eta:  0s          
#>   sampling                                           0/1000 | eta:  ?s            sampling ==                                       50/1000 | eta:  1s            sampling ====                                    100/1000 | eta:  1s            sampling ======                                  150/1000 | eta:  1s            sampling ========                                200/1000 | eta:  1s            sampling ==========                              250/1000 | eta:  1s            sampling ===========                             300/1000 | eta:  1s            sampling =============                           350/1000 | eta:  1s            sampling ===============                         400/1000 | eta:  1s            sampling =================                       450/1000 | eta:  1s            sampling ===================                     500/1000 | eta:  1s            sampling =====================                   550/1000 | eta:  1s            sampling =======================                 600/1000 | eta:  0s            sampling =========================               650/1000 | eta:  0s            sampling ===========================             700/1000 | eta:  0s            sampling ============================            750/1000 | eta:  0s            sampling ==============================          800/1000 | eta:  0s            sampling ================================        850/1000 | eta:  0s            sampling ==================================      900/1000 | eta:  0s            sampling ====================================    950/1000 | eta:  0s            sampling ====================================== 1000/1000 | eta:  0s

# far too long
head(draws)
#> $`11`
#> Markov Chain Monte Carlo (MCMC) output:
#> Start = 1 
#> End = 7 
#> Thinning interval = 1 
#>       alpha       beta
#> 1 1.0098794  1.5652410
#> 2 0.8119695 -0.1817819
#> 3 1.1721394 -0.1764524
#> 4 0.5217709 -0.5796415
#> 5 0.7567756 -0.8293186
#> 6 0.7567756 -0.8293186
#> 7 1.6888979 -1.1752022
#> 
#> $`12`
#> Markov Chain Monte Carlo (MCMC) output:
#> Start = 1 
#> End = 7 
#> Thinning interval = 1 
#>       alpha        beta
#> 1 0.8478702  0.04251455
#> 2 0.7490954 -1.36782292
#> 3 1.8757218 -0.66330474
#> 4 0.7332660 -1.16291451
#> 5 0.5350540  1.04544727
#> 6 1.3651053  1.11545433
#> 7 1.3963518 -0.54946304
#> 
#> $`13`
#> Markov Chain Monte Carlo (MCMC) output:
#> Start = 1 
#> End = 7 
#> Thinning interval = 1 
#>       alpha       beta
#> 1 1.4183309  1.1003982
#> 2 1.4183309  1.1003982
#> 3 0.5230580  0.7105599
#> 4 0.5230580  0.7105599
#> 5 1.3432723 -0.7030401
#> 6 1.8612860 -0.9181379
#> 7 0.7488582 -0.9505341
#> 
#> $`14`
#> Markov Chain Monte Carlo (MCMC) output:
#> Start = 1 
#> End = 7 
#> Thinning interval = 1 
#>       alpha        beta
#> 1 1.0579056  0.33659352
#> 2 0.7601833  1.29742984
#> 3 0.5520103 -0.28699120
#> 4 0.0418236  0.65613885
#> 5 0.1473088 -0.74730675
#> 6 0.6022979  1.16601827
#> 7 0.7895472 -0.01477612
#> 
#> attr(,"class")
#> [1] "mcmc.list"

summary(draws)
#> 
#> Iterations = 1:1000
#> Thinning interval = 1 
#> Number of chains = 4 
#> Sample size per chain = 1000 
#> 
#> 1. Empirical mean and standard deviation for each variable,
#>    plus standard error of the mean:
#> 
#>           Mean     SD Naive SE Time-series SE
#> alpha  0.77562 0.5781 0.009141        0.01493
#> beta  -0.02144 1.0064 0.015912        0.05173
#> 
#> 2. Quantiles for each variable:
#> 
#>           2.5%     25%     50%    75% 97.5%
#> alpha  0.03253  0.3129 0.65606 1.1171 2.188
#> beta  -1.99298 -0.7478 0.01208 0.7063 1.902

class(draws)
#> [1] "greta_mcmc_list" "mcmc.list"

print.greta_mcmc_list <- function(x, ...){
  n_chain <- coda::nchain(draws)
  n_iter <- coda::niter(draws)
  n_thin <- coda::thin(draws)
  cli::cli_h1("MCMC draws from {.pkg greta}")
  cli::cli_bullets(
    c(
      "*" = "Iteration = {n_iter}",
      "*" = "Chains  = {n_chain}",
      "*" = "Thinning  = {n_thin}"
    )
  )

  draws_head <- lapply(draws, head, n = 2)

  cli::cli_h1("Chain 1 (first 3 iterations)")

  flat_mat <- as.matrix(draws_head[[1]])

  print(flat_mat)

  cli::cli_alert_info(
    c("To see the values from each chain, do:\n",
      "{.run draws[[1]]}"
    )
  )
  cli::cli_alert_info(
    text = c("To print all draws, set:\n",
             "{.run options(greta_max_draws_print = Inf)}")
  )

}

draws
#> 
#> ── MCMC draws from greta ───────────────────────────────────────────────────────
#> • Iteration = 1000
#> • Chains = 4
#> • Thinning = 1
#> 
#> ── Chain 1 (first 3 iterations) ────────────────────────────────────────────────
#>          alpha       beta
#> [1,] 1.0098794  1.5652410
#> [2,] 0.8119695 -0.1817819
#> [3,] 1.1721394 -0.1764524
#> ℹ To see the values from each chain, do:
#> `draws[[1]]`
#> ℹ To print all draws, set:
#> `options(greta_max_draws_print = Inf)`

Created on 2024-05-14 with reprex v2.1.0

Session info ``` r sessioninfo::session_info() #> ─ Session info ─────────────────────────────────────────────────────────────── #> setting value #> version R version 4.3.3 (2024-02-29) #> os macOS Sonoma 14.3.1 #> system aarch64, darwin20 #> ui X11 #> language (EN) #> collate en_US.UTF-8 #> ctype en_US.UTF-8 #> tz Australia/Brisbane #> date 2024-05-14 #> pandoc 3.1.13 @ /opt/homebrew/bin/ (via rmarkdown) #> #> ─ Packages ─────────────────────────────────────────────────────────────────── #> package * version date (UTC) lib source #> abind 1.4-5 2016-07-21 [1] CRAN (R 4.3.0) #> backports 1.4.1 2021-12-13 [1] CRAN (R 4.3.0) #> base64enc 0.1-3 2015-07-28 [1] CRAN (R 4.3.0) #> callr 3.7.6 2024-03-25 [1] CRAN (R 4.3.1) #> cli 3.6.2 2023-12-11 [1] CRAN (R 4.3.1) #> coda 0.19-4.1 2024-01-31 [2] CRAN (R 4.3.1) #> codetools 0.2-20 2024-03-31 [2] CRAN (R 4.3.1) #> crayon 1.5.2 2022-09-29 [1] CRAN (R 4.3.0) #> digest 0.6.35 2024-03-11 [1] CRAN (R 4.3.1) #> evaluate 0.23 2023-11-01 [1] CRAN (R 4.3.1) #> fastmap 1.1.1 2023-02-24 [1] CRAN (R 4.3.0) #> fs 1.6.4 2024-04-25 [1] CRAN (R 4.3.1) #> future 1.33.2 2024-03-26 [1] CRAN (R 4.3.1) #> globals 0.16.3 2024-03-08 [1] CRAN (R 4.3.1) #> glue 1.7.0 2024-01-09 [1] CRAN (R 4.3.1) #> greta * 0.4.5.9000 2024-05-13 [1] local #> hms 1.1.3 2023-03-21 [1] CRAN (R 4.3.0) #> htmltools 0.5.8.1 2024-04-04 [1] CRAN (R 4.3.1) #> jsonlite 1.8.8 2023-12-04 [1] CRAN (R 4.3.1) #> knitr 1.45 2023-10-30 [1] CRAN (R 4.3.1) #> lattice 0.22-6 2024-03-20 [1] CRAN (R 4.3.1) #> lifecycle 1.0.4 2023-11-07 [1] CRAN (R 4.3.1) #> listenv 0.9.1 2024-01-29 [2] CRAN (R 4.3.1) #> magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.3.0) #> Matrix 1.6-5 2024-01-11 [1] CRAN (R 4.3.1) #> parallelly 1.37.1 2024-02-29 [1] CRAN (R 4.3.1) #> pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.3.0) #> png 0.1-8 2022-11-29 [1] CRAN (R 4.3.0) #> prettyunits 1.2.0 2023-09-24 [1] CRAN (R 4.3.1) #> processx 3.8.4 2024-03-16 [1] CRAN (R 4.3.1) #> progress 1.2.3 2023-12-06 [1] CRAN (R 4.3.1) #> ps 1.7.6 2024-01-18 [1] CRAN (R 4.3.1) #> purrr 1.0.2 2023-08-10 [1] CRAN (R 4.3.0) #> R.cache 0.16.0 2022-07-21 [2] CRAN (R 4.3.0) #> R.methodsS3 1.8.2 2022-06-13 [2] CRAN (R 4.3.0) #> R.oo 1.26.0 2024-01-24 [2] CRAN (R 4.3.1) #> R.utils 2.12.3 2023-11-18 [2] CRAN (R 4.3.1) #> R6 2.5.1 2021-08-19 [1] CRAN (R 4.3.0) #> Rcpp 1.0.12 2024-01-09 [1] CRAN (R 4.3.1) #> reprex 2.1.0 2024-01-11 [2] CRAN (R 4.3.1) #> reticulate 1.36.1 2024-04-22 [1] CRAN (R 4.3.1) #> rlang 1.1.3 2024-01-10 [1] CRAN (R 4.3.1) #> rmarkdown 2.26 2024-03-05 [1] CRAN (R 4.3.1) #> rstudioapi 0.16.0 2024-03-24 [1] CRAN (R 4.3.1) #> sessioninfo 1.2.2 2021-12-06 [2] CRAN (R 4.3.0) #> styler 1.10.3 2024-04-07 [2] CRAN (R 4.3.1) #> tensorflow 2.16.0 2024-04-15 [2] CRAN (R 4.3.1) #> tfautograph 0.3.2 2021-09-17 [2] CRAN (R 4.3.0) #> tfruns 1.5.3 2024-04-19 [1] CRAN (R 4.3.1) #> vctrs 0.6.5 2023-12-01 [1] CRAN (R 4.3.1) #> whisker 0.4.1 2022-12-05 [1] CRAN (R 4.3.0) #> withr 3.0.0 2024-01-16 [1] CRAN (R 4.3.1) #> xfun 0.43 2024-03-25 [1] CRAN (R 4.3.1) #> yaml 2.3.8 2023-12-11 [1] CRAN (R 4.3.1) #> #> [1] /Users/nick/Library/R/arm64/4.3/library #> [2] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library #> #> ─ Python configuration ─────────────────────────────────────────────────────── #> python: /Users/nick/Library/r-miniconda-arm64/envs/greta-env-tf2/bin/python #> libpython: /Users/nick/Library/r-miniconda-arm64/envs/greta-env-tf2/lib/libpython3.11.dylib #> pythonhome: /Users/nick/Library/r-miniconda-arm64/envs/greta-env-tf2:/Users/nick/Library/r-miniconda-arm64/envs/greta-env-tf2 #> version: 3.11.9 | packaged by conda-forge | (main, Apr 19 2024, 18:34:54) [Clang 16.0.6 ] #> numpy: /Users/nick/Library/r-miniconda-arm64/envs/greta-env-tf2/lib/python3.11/site-packages/numpy #> numpy_version: 1.26.4 #> tensorflow: /Users/nick/Library/r-miniconda-arm64/envs/greta-env-tf2/lib/python3.11/site-packages/tensorflow #> #> NOTE: Python version was forced by use_python() function #> #> ────────────────────────────────────────────────────────────────────────────── ```
njtierney commented 2 months ago

Some more thoughts/ideas / concerns about printing speed.

library(greta)
#> 
#> Attaching package: 'greta'
#> The following objects are masked from 'package:stats':
#> 
#>     binomial, cov2cor, poisson
#> The following objects are masked from 'package:base':
#> 
#>     %*%, apply, backsolve, beta, chol2inv, colMeans, colSums, diag,
#>     eigen, forwardsolve, gamma, identity, rowMeans, rowSums, sweep,
#>     tapply
beta <- normal(0,1)
#> ℹ Initialising python and checking dependencies, this may take a moment.
#> ✔ Initialising python and checking dependencies ... done!
#> 
alpha <- normal(0, 1, truncation = c(0, Inf))

m <- model(alpha, beta)

draws <- mcmc(m)
#> running 4 chains simultaneously on up to 8 CPU cores
#> 
#>     warmup                                           0/1000 | eta:  ?s              warmup ==                                       50/1000 | eta: 11s              warmup ====                                    100/1000 | eta:  6s              warmup ======                                  150/1000 | eta:  4s              warmup ========                                200/1000 | eta:  4s              warmup ==========                              250/1000 | eta:  3s              warmup ===========                             300/1000 | eta:  2s              warmup =============                           350/1000 | eta:  2s              warmup ===============                         400/1000 | eta:  2s              warmup =================                       450/1000 | eta:  2s              warmup ===================                     500/1000 | eta:  1s              warmup =====================                   550/1000 | eta:  1s              warmup =======================                 600/1000 | eta:  1s              warmup =========================               650/1000 | eta:  1s              warmup ===========================             700/1000 | eta:  1s              warmup ============================            750/1000 | eta:  1s              warmup ==============================          800/1000 | eta:  0s              warmup ================================        850/1000 | eta:  0s              warmup ==================================      900/1000 | eta:  0s              warmup ====================================    950/1000 | eta:  0s              warmup ====================================== 1000/1000 | eta:  0s          
#>   sampling                                           0/1000 | eta:  ?s            sampling ==                                       50/1000 | eta:  1s            sampling ====                                    100/1000 | eta:  1s            sampling ======                                  150/1000 | eta:  1s            sampling ========                                200/1000 | eta:  1s            sampling ==========                              250/1000 | eta:  1s            sampling ===========                             300/1000 | eta:  1s            sampling =============                           350/1000 | eta:  1s            sampling ===============                         400/1000 | eta:  1s            sampling =================                       450/1000 | eta:  1s            sampling ===================                     500/1000 | eta:  1s            sampling =====================                   550/1000 | eta:  1s            sampling =======================                 600/1000 | eta:  0s            sampling =========================               650/1000 | eta:  0s            sampling ===========================             700/1000 | eta:  0s            sampling ============================            750/1000 | eta:  0s            sampling ==============================          800/1000 | eta:  0s            sampling ================================        850/1000 | eta:  0s            sampling ==================================      900/1000 | eta:  0s            sampling ====================================    950/1000 | eta:  0s            sampling ====================================== 1000/1000 | eta:  0s

summary(draws)
#> 
#> Iterations = 1:1000
#> Thinning interval = 1 
#> Number of chains = 4 
#> Sample size per chain = 1000 
#> 
#> 1. Empirical mean and standard deviation for each variable,
#>    plus standard error of the mean:
#> 
#>          Mean     SD Naive SE Time-series SE
#> alpha 0.76714 0.5856 0.009259        0.01582
#> beta  0.04531 1.0095 0.015962        0.02495
#> 
#> 2. Quantiles for each variable:
#> 
#>           2.5%     25%     50%    75% 97.5%
#> alpha  0.02773  0.3009 0.66052 1.1153 2.194
#> beta  -1.96152 -0.6379 0.06362 0.7134 2.052
class(draws)
#> [1] "greta_mcmc_list" "mcmc.list"

print.greta_mcmc_list <- function(x, ..., n = 3){

  n_chain <- coda::nchain(x)
  n_iter <- coda::niter(x)
  n_thin <- coda::thin(x)
  cli::cli_h1("MCMC draws from {.pkg greta}")
  cli::cli_bullets(
    c(
      "*" = "Iteration = {n_iter}",
      "*" = "Chains  = {n_chain}",
      "*" = "Thinning  = {n_thin}"
    )
  )

  n_print <- getOption("greta.print_max") %||% n

  cli::cli_h1("Chain 1 (first {n_print} iterations)")

  flat_mat <- as.matrix(x[[1]])

  draws_head <- head(flat_mat, n = n_print)

  remaining_draws <- n_iter - n_print
  print(draws_head)
  cli::cli_alert_info(
    text = c(
      "i" = "{remaining_draws} more draws\n",
      "i" = "Use {.code print(n = ...)} to see more draws"
      )
  )

  cli::cli_rule()

  cli::cli_alert_info(
    c("View {.pkg greta} draw chains with:\n",
      "{.code greta_draws[[1]]}"
    )
  )

  cli::cli_alert_info(
    c("To see draws summary run:\n",
      "{.code summary(greta_draws)}")
  )
  cli::cli_alert_info(
    c("To see diagnostics, run:\n",
      "")
  )

}

print.greta_mcmc_list2 <- function(x, ..., n = 3){

  n_chain <- coda::nchain(x)
  n_iter <- coda::niter(x)
  n_thin <- coda::thin(x)
  cat("MCMC draws from `greta` \n")
  cat(
      sprintf(""),
      sprintf("Iteration = %s \n", n_iter),
      sprintf("Chains = %s \n",n_chain),
      sprintf("Thinning = %s \n", n_thin)
    )

  n_print <- getOption("greta.print_max") %||% n

  cat(
    sprintf("\nChain 1 (first %s iterations)\n\n", n_print)
  )

  flat_mat <- as.matrix(x[[1]])

  draws_head <- head(flat_mat, n = n_print)

  cat(sprintf(""))

  remaining_draws <- n_iter - n_print
  print(draws_head)
  cat(
      sprintf(""),
      sprintf("\ni: %s more draws\n", remaining_draws),
      sprintf("i: Use `print(n = ...)` to see more draws\n")
  )

  cat(
    sprintf(""),
    sprintf("View `greta` draw chains with:\n"),
    sprintf("`greta_draws[[1]]`")
    )

}

draws_mcmc <- coda::as.mcmc.list(draws)

draws2 <- draws
class(draws2) <- c("greta_mcmc_list2", class(draws2))

draws
#> 
#> ── MCMC draws from greta ───────────────────────────────────────────────────────
#> • Iteration = 1000
#> • Chains = 4
#> • Thinning = 1
#> 
#> ── Chain 1 (first 3 iterations) ────────────────────────────────────────────────
#>          alpha      beta
#> [1,] 0.6815562 1.5431265
#> [2,] 0.3787658 0.5363900
#> [3,] 0.9252470 0.3406627
#> ℹ 997 more draws
#> Use `print(n = ...)` to see more draws
#> ────────────────────────────────────────────────────────────────────────────────
#> ℹ View greta draw chains with:
#> `greta_draws[[1]]`
#> ℹ To see draws summary run:
#> `summary(greta_draws)`
#> ℹ To see diagnostics, run:
draws2
#> MCMC draws from `greta` 
#>  Iteration = 1000 
#>  Chains = 4 
#>  Thinning = 1 
#> 
#> Chain 1 (first 3 iterations)
#> 
#>          alpha      beta
#> [1,] 0.6815562 1.5431265
#> [2,] 0.3787658 0.5363900
#> [3,] 0.9252470 0.3406627
#>  
#> i: 997 more draws
#>  i: Use `print(n = ...)` to see more draws
#>  View `greta` draw chains with:
#>  `greta_draws[[1]]`
quiet_bm <- purrr::quietly(bench::mark)
bm <- quiet_bm(
  greta = print.greta_mcmc_list(draws),
  greta2 = print.greta_mcmc_list2(draws),
  coda = print(draws_mcmc),
  check = FALSE
)

bm$result
#> # A tibble: 3 × 6
#>   expression      min   median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#> 1 greta        13.9ms     14ms      70.3  125.09KB     75.0
#> 2 greta2      104.6µs    109µs    8672.    27.48KB     14.6
#> 3 coda         20.9ms     21ms      44.6    9.92KB      0
plot(bm$result)
#> Loading required namespace: tidyr

summary(bm$result, relative = TRUE)
#> # A tibble: 3 × 6
#>   expression   min median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr> <dbl>  <dbl>     <dbl>     <dbl>    <dbl>
#> 1 greta       133.   128.      1.58     12.6       Inf
#> 2 greta2        1      1     194.        2.77      Inf
#> 3 coda        199.   192.      1         1         NaN

print.greta_mcmc_list(draws)
#> 
#> ── MCMC draws from greta ───────────────────────────────────────────────────────
#> • Iteration = 1000
#> • Chains = 4
#> • Thinning = 1
#> 
#> ── Chain 1 (first 3 iterations) ────────────────────────────────────────────────
#>          alpha      beta
#> [1,] 0.6815562 1.5431265
#> [2,] 0.3787658 0.5363900
#> [3,] 0.9252470 0.3406627
#> ℹ 997 more draws
#> Use `print(n = ...)` to see more draws
#> ────────────────────────────────────────────────────────────────────────────────
#> ℹ View greta draw chains with:
#> `greta_draws[[1]]`
#> ℹ To see draws summary run:
#> `summary(greta_draws)`
#> ℹ To see diagnostics, run:
print.greta_mcmc_list2(draws)
#> MCMC draws from `greta` 
#>  Iteration = 1000 
#>  Chains = 4 
#>  Thinning = 1 
#> 
#> Chain 1 (first 3 iterations)
#> 
#>          alpha      beta
#> [1,] 0.6815562 1.5431265
#> [2,] 0.3787658 0.5363900
#> [3,] 0.9252470 0.3406627
#>  
#> i: 997 more draws
#>  i: Use `print(n = ...)` to see more draws
#>  View `greta` draw chains with:
#>  `greta_draws[[1]]`
# cutting this off for demo pruposes
print(head(draws_mcmc))
#> $`11`
#> Markov Chain Monte Carlo (MCMC) output:
#> Start = 1 
#> End = 7 
#> Thinning interval = 1 
#>       alpha       beta
#> 1 0.6815562  1.5431265
#> 2 0.3787658  0.5363900
#> 3 0.9252470  0.3406627
#> 4 1.0660587 -1.1876874
#> 5 1.0660587 -1.1876874
#> 6 0.9276765 -0.3032537
#> 7 0.7523860 -0.4157797
#> 
#> $`12`
#> Markov Chain Monte Carlo (MCMC) output:
#> Start = 1 
#> End = 7 
#> Thinning interval = 1 
#>        alpha       beta
#> 1 1.20572213  1.3850561
#> 2 1.62266329  1.8091175
#> 3 0.46303666  1.7910581
#> 4 0.41465866 -0.8458950
#> 5 0.41465866 -0.8458950
#> 6 0.07696906  1.8992183
#> 7 0.66109078  0.2877945
#> 
#> $`13`
#> Markov Chain Monte Carlo (MCMC) output:
#> Start = 1 
#> End = 7 
#> Thinning interval = 1 
#>        alpha       beta
#> 1 1.33663613 -1.1896738
#> 2 1.50322305 -0.4703715
#> 3 2.47498098 -0.1181150
#> 4 0.31774948 -0.4843053
#> 5 0.07900174  0.5481055
#> 6 0.07900174  0.5481055
#> 7 0.07900174  0.5481055
#> 
#> $`14`
#> Markov Chain Monte Carlo (MCMC) output:
#> Start = 1 
#> End = 7 
#> Thinning interval = 1 
#>       alpha       beta
#> 1 0.5895023 -0.8248683
#> 2 0.6440894 -0.8667017
#> 3 0.6440894 -0.8667017
#> 4 0.3676444  0.3384980
#> 5 1.1680652 -0.8176417
#> 6 0.2699316 -0.6854730
#> 7 2.0256743  1.1436656
#> 
#> attr(,"class")
#> [1] "mcmc.list"

x <- 5
bm_prints <- quiet_bm(
  paste0 = paste0("Iteration = ", x),
  sprintf = sprintf("Iteration = %s", x)
)

bm_prints$result
#> # A tibble: 2 × 6
#>   expression      min   median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#> 1 paste0       1.44µs   1.56µs   582634.        0B        0
#> 2 sprintf      1.07µs   1.19µs   768384.        0B        0

## design considerations -
## * How does the print method handle many many parameters
## * Burn in/warmup information?
## *

Created on 2024-07-24 with reprex v2.1.0

Session info ``` r sessioninfo::session_info() #> ─ Session info ─────────────────────────────────────────────────────────────── #> setting value #> version R version 4.4.0 (2024-04-24) #> os macOS Sonoma 14.5 #> system aarch64, darwin20 #> ui X11 #> language (EN) #> collate en_US.UTF-8 #> ctype en_US.UTF-8 #> tz Australia/Hobart #> date 2024-07-24 #> pandoc 3.2.1 @ /opt/homebrew/bin/ (via rmarkdown) #> #> ─ Packages ─────────────────────────────────────────────────────────────────── #> package * version date (UTC) lib source #> abind 1.4-5 2016-07-21 [1] CRAN (R 4.4.0) #> backports 1.5.0 2024-05-23 [1] CRAN (R 4.4.0) #> base64enc 0.1-3 2015-07-28 [1] CRAN (R 4.4.0) #> beeswarm 0.4.0 2021-06-01 [1] CRAN (R 4.4.0) #> bench 1.1.3 2023-05-04 [1] CRAN (R 4.4.0) #> callr 3.7.6 2024-03-25 [1] CRAN (R 4.4.0) #> cli 3.6.3 2024-06-21 [1] CRAN (R 4.4.0) #> coda 0.19-4.1 2024-01-31 [1] CRAN (R 4.4.0) #> codetools 0.2-20 2024-03-31 [2] CRAN (R 4.4.0) #> colorspace 2.1-0 2023-01-23 [1] CRAN (R 4.4.0) #> crayon 1.5.3 2024-06-20 [1] CRAN (R 4.4.0) #> curl 5.2.1 2024-03-01 [1] CRAN (R 4.4.0) #> digest 0.6.36 2024-06-23 [1] CRAN (R 4.4.0) #> dplyr 1.1.4 2023-11-17 [1] CRAN (R 4.4.0) #> evaluate 0.24.0 2024-06-10 [1] CRAN (R 4.4.0) #> fansi 1.0.6 2023-12-08 [1] CRAN (R 4.4.0) #> farver 2.1.2 2024-05-13 [1] CRAN (R 4.4.0) #> fastmap 1.2.0 2024-05-15 [1] CRAN (R 4.4.0) #> fs 1.6.4.9000 2024-06-26 [1] Github (r-lib/fs@714990b) #> future 1.33.2 2024-03-26 [1] CRAN (R 4.4.0) #> generics 0.1.3 2022-07-05 [1] CRAN (R 4.4.0) #> ggbeeswarm 0.7.2 2023-04-29 [1] CRAN (R 4.4.0) #> ggplot2 3.5.1 2024-04-23 [1] CRAN (R 4.4.0) #> globals 0.16.3 2024-03-08 [1] CRAN (R 4.4.0) #> glue 1.7.0 2024-01-09 [1] CRAN (R 4.4.0) #> greta * 0.4.5.9000 2024-07-24 [1] local #> gtable 0.3.5 2024-04-22 [1] CRAN (R 4.4.0) #> highr 0.11 2024-05-26 [1] CRAN (R 4.4.0) #> hms 1.1.3 2023-03-21 [1] CRAN (R 4.4.0) #> htmltools 0.5.8.1 2024-04-04 [1] CRAN (R 4.4.0) #> jsonlite 1.8.8 2023-12-04 [1] CRAN (R 4.4.0) #> knitr 1.48 2024-07-07 [1] CRAN (R 4.4.0) #> labeling 0.4.3 2023-08-29 [1] CRAN (R 4.4.0) #> lattice 0.22-6 2024-03-20 [2] CRAN (R 4.4.0) #> lifecycle 1.0.4 2023-11-07 [1] CRAN (R 4.4.0) #> listenv 0.9.1 2024-01-29 [1] CRAN (R 4.4.0) #> magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.4.0) #> Matrix 1.7-0 2024-03-22 [2] CRAN (R 4.4.0) #> munsell 0.5.1 2024-04-01 [1] CRAN (R 4.4.0) #> parallelly 1.37.1 2024-02-29 [1] CRAN (R 4.4.0) #> pillar 1.9.0 2023-03-22 [1] CRAN (R 4.4.0) #> pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.4.0) #> png 0.1-8 2022-11-29 [1] CRAN (R 4.4.0) #> prettyunits 1.2.0 2023-09-24 [1] CRAN (R 4.4.0) #> processx 3.8.4 2024-03-16 [1] CRAN (R 4.4.0) #> profmem 0.6.0 2020-12-13 [1] CRAN (R 4.4.0) #> progress 1.2.3 2023-12-06 [1] CRAN (R 4.4.0) #> ps 1.7.7 2024-07-02 [1] CRAN (R 4.4.0) #> purrr 1.0.2 2023-08-10 [1] CRAN (R 4.4.0) #> R.cache 0.16.0 2022-07-21 [1] CRAN (R 4.4.0) #> R.methodsS3 1.8.2 2022-06-13 [1] CRAN (R 4.4.0) #> R.oo 1.26.0 2024-01-24 [1] CRAN (R 4.4.0) #> R.utils 2.12.3 2023-11-18 [1] CRAN (R 4.4.0) #> R6 2.5.1 2021-08-19 [1] CRAN (R 4.4.0) #> Rcpp 1.0.12 2024-01-09 [1] CRAN (R 4.4.0) #> reprex 2.1.0 2024-01-11 [1] CRAN (R 4.4.0) #> reticulate 1.36.1 2024-04-22 [1] CRAN (R 4.4.0) #> rlang 1.1.4 2024-06-04 [1] CRAN (R 4.4.0) #> rmarkdown 2.27 2024-05-17 [1] CRAN (R 4.4.0) #> rstudioapi 0.16.0 2024-03-24 [1] CRAN (R 4.4.0) #> scales 1.3.0 2023-11-28 [1] CRAN (R 4.4.0) #> sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.4.0) #> styler 1.10.3 2024-04-07 [1] CRAN (R 4.4.0) #> tensorflow 2.16.0 2024-04-15 [1] CRAN (R 4.4.0) #> tfautograph 0.3.2 2021-09-17 [1] CRAN (R 4.4.0) #> tfruns 1.5.3 2024-04-19 [1] CRAN (R 4.4.0) #> tibble 3.2.1 2023-03-20 [1] CRAN (R 4.4.0) #> tidyr 1.3.1 2024-01-24 [1] CRAN (R 4.4.0) #> tidyselect 1.2.1 2024-03-11 [1] CRAN (R 4.4.0) #> utf8 1.2.4 2023-10-22 [1] CRAN (R 4.4.0) #> vctrs 0.6.5 2023-12-01 [1] CRAN (R 4.4.0) #> vipor 0.4.7 2023-12-18 [1] CRAN (R 4.4.0) #> whisker 0.4.1 2022-12-05 [1] CRAN (R 4.4.0) #> withr 3.0.0 2024-01-16 [1] CRAN (R 4.4.0) #> xfun 0.45 2024-06-16 [1] CRAN (R 4.4.0) #> xml2 1.3.6 2023-12-04 [1] CRAN (R 4.4.0) #> yaml 2.3.9 2024-07-05 [1] CRAN (R 4.4.0) #> #> [1] /Users/nick/Library/R/arm64/4.4/library #> [2] /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/library #> #> ─ Python configuration ─────────────────────────────────────────────────────── #> python: /Users/nick/Library/r-miniconda-arm64/envs/greta-env-tf2/bin/python #> libpython: /Users/nick/Library/r-miniconda-arm64/envs/greta-env-tf2/lib/libpython3.11.dylib #> pythonhome: /Users/nick/Library/r-miniconda-arm64/envs/greta-env-tf2:/Users/nick/Library/r-miniconda-arm64/envs/greta-env-tf2 #> version: 3.11.9 | packaged by conda-forge | (main, Apr 19 2024, 18:34:54) [Clang 16.0.6 ] #> numpy: /Users/nick/Library/r-miniconda-arm64/envs/greta-env-tf2/lib/python3.11/site-packages/numpy #> numpy_version: 1.26.4 #> tensorflow: /Users/nick/Library/r-miniconda-arm64/envs/greta-env-tf2/lib/python3.11/site-packages/tensorflow #> #> NOTE: Python version was forced by use_python() function #> #> ────────────────────────────────────────────────────────────────────────────── ```