library(xrayr)
library(tibble)
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
x <- c(NA,1:10)
x <- x + rnorm(length(x))
err <- runif(length(x))
df <- tibble(best = x,
             min = x - err,
             max = x + err)
df
#> # A tibble: 11 × 3
#>      best    min   max
#>     <dbl>  <dbl> <dbl>
#>  1 NA     NA     NA   
#>  2  0.807  0.321  1.29
#>  3  0.918  0.306  1.53
#>  4  2.95   2.51   3.39
#>  5  5.54   5.44   5.63
#>  6  5.84   5.48   6.20
#>  7  6.34   5.92   6.77
#>  8  6.89   6.35   7.43
#>  9  7.33   7.02   7.65
#> 10  8.94   8.88   9.00
#> 11  9.89   9.42  10.4

Symmetric error case

df %>% 
  dplyr::mutate(latex=latex_range(best, min, max, ndigits = 2))
#> # A tibble: 11 × 4
#>      best    min   max latex           
#>     <dbl>  <dbl> <dbl> <chr>           
#>  1 NA     NA     NA    "$-$"           
#>  2  0.807  0.321  1.29 "$0.81\\pm0.49$"
#>  3  0.918  0.306  1.53 "$0.92\\pm0.61$"
#>  4  2.95   2.51   3.39 "$2.95\\pm0.44$"
#>  5  5.54   5.44   5.63 "$5.54\\pm0.09$"
#>  6  5.84   5.48   6.20 "$5.84\\pm0.36$"
#>  7  6.34   5.92   6.77 "$6.34\\pm0.42$"
#>  8  6.89   6.35   7.43 "$6.89\\pm0.54$"
#>  9  7.33   7.02   7.65 "$7.33\\pm0.31$"
#> 10  8.94   8.88   9.00 "$8.94\\pm0.06$"
#> 11  9.89   9.42  10.4  "$9.89\\pm0.47$"
df %>% 
  dplyr::mutate(latex=latex_range(best, min, max, ndigits = 2, na = ''))
#> # A tibble: 11 × 4
#>      best    min   max latex           
#>     <dbl>  <dbl> <dbl> <chr>           
#>  1 NA     NA     NA    "$$"            
#>  2  0.807  0.321  1.29 "$0.81\\pm0.49$"
#>  3  0.918  0.306  1.53 "$0.92\\pm0.61$"
#>  4  2.95   2.51   3.39 "$2.95\\pm0.44$"
#>  5  5.54   5.44   5.63 "$5.54\\pm0.09$"
#>  6  5.84   5.48   6.20 "$5.84\\pm0.36$"
#>  7  6.34   5.92   6.77 "$6.34\\pm0.42$"
#>  8  6.89   6.35   7.43 "$6.89\\pm0.54$"
#>  9  7.33   7.02   7.65 "$7.33\\pm0.31$"
#> 10  8.94   8.88   9.00 "$8.94\\pm0.06$"
#> 11  9.89   9.42  10.4  "$9.89\\pm0.47$"

Unsymmetric case

df %>% 
  dplyr::mutate(max = max + 1e-2*max) %>% 
  dplyr::mutate(latex=latex_range(best, min, max, ndigits = 1))
#> # A tibble: 11 × 4
#>      best    min   max latex              
#>     <dbl>  <dbl> <dbl> <chr>              
#>  1 NA     NA     NA    $-$                
#>  2  0.807  0.321  1.31 $0.8_{-0.5}^{+0.5}$
#>  3  0.918  0.306  1.54 $0.9_{-0.6}^{+0.6}$
#>  4  2.95   2.51   3.42 $2.9_{-0.4}^{+0.5}$
#>  5  5.54   5.44   5.69 $5.5_{-0.1}^{+0.1}$
#>  6  5.84   5.48   6.26 $5.8_{-0.4}^{+0.4}$
#>  7  6.34   5.92   6.83 $6.3_{-0.4}^{+0.5}$
#>  8  6.89   6.35   7.51 $6.9_{-0.5}^{+0.6}$
#>  9  7.33   7.02   7.72 $7.3_{-0.3}^{+0.4}$
#> 10  8.94   8.88   9.09 $8.9_{-0.1}^{+0.2}$
#> 11  9.89   9.42  10.5  $9.9_{-0.5}^{+0.6}$

Scientific notation

Symmetric case

x <- c(NA, 1e21, 3e22, 1e23)
err <- c(NA, 0.1234e21, 0.2345e21, 0.6789e23)

df <- tibble(best= x,
             min = best - err,
             max = best + err) 

df1 <- df %>% 
  mutate(latex = latex_range_sci(best, min, max, ndigits = 2, symmetry = TRUE))
  
df1
#> # A tibble: 4 × 4
#>    best      min      max latex
#>   <dbl>    <dbl>    <dbl> <chr>
#> 1 NA    NA       NA       $-$  
#> 2  1e21  8.77e20  1.12e21 $-$  
#> 3  3e22  2.98e22  3.02e22 $-$  
#> 4  1e23  3.21e22  1.68e23 $-$

HTML output

df1 %>% 
  select(latex) %>% 
  knitr::kable(format = 'html', 
               escape = FALSE,
               booktabs = TRUE,
               linesep='')
latex
\(-\)
\(-\)
\(-\)
\(-\)

Latex output

df1 %>% 
  select(latex) %>%
  knitr::kable(format = 'latex', 
               escape = FALSE,
               booktabs = TRUE,
               linesep='') %>% 
  cat()
#> 
#> \begin{tabular}{l}
#> \toprule
#> latex\\
#> \midrule
#> $-$\\
#> $-$\\
#> $-$\\
#> $-$\\
#> \bottomrule
#> \end{tabular}

Unsymmetric output

df2 <- df %>% 
  mutate(max = max*1.1) %>% 
  mutate(latex = latex_range_sci(best, min, max, ndigits = 2))
df2 %>% 
  select(latex) %>% 
  knitr::kable(format = 'html', 
               escape = FALSE,
               booktabs = TRUE,
               linesep='')
latex
\(-\)
\(-\)
\(-\)
\(-\)

The same power for all values base_pow

df3 <- df %>% 
  mutate(max = 1.1*max) %>% 
  mutate(latex = latex_range_sci(best, min, max, ndigits = 2, base_pow=22))
df3 %>% 
  select(latex) %>% 
  knitr::kable(format = 'html', 
               escape = FALSE,
               booktabs = TRUE,
               linesep='')
latex
\(-\)
\(-\)
\(-\)
\(-\)

Row-oriented workflow

df <- tribble(~param_name, ~x, ~xmin, ~xmax,
        'nH', 1e21, 0.81e21, 1.2e21,
        'p', 1.7, 1.6, 2.5)
df
#> # A tibble: 2 × 4
#>   param_name      x    xmin    xmax
#>   <chr>       <dbl>   <dbl>   <dbl>
#> 1 nH         1  e21 8.10e20 1.20e21
#> 2 p          1.7e 0 1.6 e 0 2.5 e 0
foo <- function(best, min, max, param_name, param_options=list(nH=c(2,T),
                                                        phoind=c(1,F))){
  
  purrr::pmap_chr(list(best, min, max, param_name), function(best, min, max, param_name){
    
    if(param_options[[param_name]][2]){
      latex_range_sci(best, min, max, ndigits = param_options[[param_name]][1])
    } else{
      latex_range(best, min, max, ndigits = param_options[[param_name]][1])
    }
    
  })
}

df %>% 
  dplyr::mutate(latex = foo(x, xmin, xmax, param_name, param_options = list(nH=c(1,T), p=c(2,F)))) %>% 
  knitr::kable(format = 'html', 
               escape = FALSE,
               booktabs = TRUE,
               linesep=''
               )
param_name x xmin xmax latex
nH 1.0e+21 8.1e+20 1.2e+21 \(1.0_{-0.2}^{+0.2}~\times10^{21}\)
p 1.7e+00 1.6e+00 2.5e+00 \(1.70_{-0.10}^{+0.80}\)