# PrettyTables diff digits highlight?

**URL:** <https://discourse.julialang.org/t/prettytables-diff-digits-highlight/92664>\
**Category:** Data\
**Tags:** package, prettytables\
**Created:** [January 8, 2023, 10:11am UTC](https://discourse.julialang.org/t/prettytables-diff-digits-highlight/92664 "2023-01-08T10:11:31Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![LaurentPlagne](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laurentplagne/32/10103_2.png) [@LaurentPlagne](https://discourse.julialang.org/u/LaurentPlagne)\
**Post date:** [January 8, 2023, 10:11am UTC](https://discourse.julialang.org/t/prettytables-diff-digits-highlight/92664/1 "2023-01-08T10:11:31Z")

</div>

Hi,

First, kudos again to @Ronis_BR for the super useful PrettyTables.jl package !

I was wondering if it could be possible to highlight diff digits between two columns with PrettyTables.jl like

![diffdigits](https://global.discourse-cdn.com/julialang/original/3X/5/4/54db8dc7cfb3142ca3d55766add6fe372858893b.png)

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [January 8, 2023, 1:25pm UTC](https://discourse.julialang.org/t/prettytables-diff-digits-highlight/92664/2 "2023-01-08T13:25:52Z")

</div>

Are you only interested in a PrettyTables solution?

---

<div class="post-metadata">

**Author:** ![LaurentPlagne](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laurentplagne/32/10103_2.png) [@LaurentPlagne](https://discourse.julialang.org/u/LaurentPlagne)\
**Post date:** [January 8, 2023, 3:46pm UTC](https://discourse.julialang.org/t/prettytables-diff-digits-highlight/92664/3 "2023-01-08T15:46:58Z")

</div>

Hi Rafael,

I first wanted to check that it was not yet possible to achieve this with PrettyTables.jl and maybe suggest that it could be a nice extension for the PT highlighters.

I would like to know if other PT users find this potential feature interesting.

Meanwhile I guess I can manage to post-process LateX Pretty tables.jl outputs to obtain what I want. I think that a direct PR in PT would be more difficult for me to achieve.

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [January 9, 2023, 4:22am UTC](https://discourse.julialang.org/t/prettytables-diff-digits-highlight/92664/4 "2023-01-09T04:22:18Z")

</div>

Hi @LaurentPlagne !

Currently, the highlighter works only on the entire cell. However, I think we can do something like this using a custom cell called `AnsiTextCell`. However, all the heavy lift (finding the diff and decorating the string) will be external to PrettyTables.jl,

I will try to do a MWE tomorrow.

---

<div class="post-metadata">

**Author:** ![LaurentPlagne](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laurentplagne/32/10103_2.png) [@LaurentPlagne](https://discourse.julialang.org/u/LaurentPlagne)\
**Post date:** [January 9, 2023, 6:41am UTC](https://discourse.julialang.org/t/prettytables-diff-digits-highlight/92664/5 "2023-01-09T06:41:02Z")

</div>

Thank you @Ronis_BR.  
This is cool that the PrettyTable.jl’s internals already allow for this.

> [@Ronis\_BR](#):
>
> I will try to do a MWE tomorrow.

No rush 😉

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [January 9, 2023, 10:18am UTC](https://discourse.julialang.org/t/prettytables-diff-digits-highlight/92664/6 "2023-01-09T10:18:14Z")

</div>

Not sure whether there is a better way to achieve this, but the following seems to “work”:

```julia
n = 10
x = rand(n)
y = x .+ 2e-3 .* (rand(n) .- 0.5)

y[1] = x[1] # test identical numbers
x[end], y[end] = (0.1, 0.99999) # what to do here?

using PrettyTables, Crayons, Printf

function text_diff(a, b)
    a_str = @sprintf "%.5f" a
    b_str = @sprintf "%.5f" b
    i = findfirst(i->a_str[i]!=b_str[i], 1:lastindex(a_str))
    if !isnothing(i)
        common = SubString(b_str,1,i-1)
        different = SubString(b_str, i)
        red = crayon"red bold"
        b_str = AnsiTextCell("$common$red$different")
    end
    [a_str b_str]
end

table = reduce(vcat, text_diff(x[i], y[i]) for i in eachindex(x))
pretty_table(table)

```

![Screenshot from 2023-01-09 11-07-08](https://global.discourse-cdn.com/julialang/original/3X/b/5/b5276cd5b3f86a10ffb50cf97d925904574308b7.png)

* * *

Note that “different digits” is actually interpreted here as “characters that are different in the decimal representation of the numbers”. But this is probably not really what you want, as I tried to illustrate in the example of the last row.

A more formal definition of the number of common (decimal) digits between two numbers a and b would involve computing a quantity like \text{floor}\left(-\text{log}\_{10}\left(\frac{|b-a|}{|a|}\right)\right). But then it gets more difficult to clearly represent it using colored digits in the decimal representation of the numbers.

---

<div class="post-metadata">

**Author:** ![LaurentPlagne](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laurentplagne/32/10103_2.png) [@LaurentPlagne](https://discourse.julialang.org/u/LaurentPlagne)\
**Post date:** [January 9, 2023, 10:28am UTC](https://discourse.julialang.org/t/prettytables-diff-digits-highlight/92664/7 "2023-01-09T10:28:35Z")

</div>

argh, I did not think about this 😊…

I guess that the solution would be to only colorize different significant digits (no coloring at all the last line in this cases) since the aim is to highlight the **numerical** difference magnitude.

Thank you anyway for the solution to this request !

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [January 9, 2023, 12:24pm UTC](https://discourse.julialang.org/t/prettytables-diff-digits-highlight/92664/8 "2023-01-09T12:24:41Z")

</div>

Hi @ffevotte !

Your solution is exactly what I had in mind. Thanks!

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [January 9, 2023, 7:38pm UTC](https://discourse.julialang.org/t/prettytables-diff-digits-highlight/92664/9 "2023-01-09T19:38:23Z")

</div>

> [@LaurentPlagne](#):
>
> I guess that the solution would be to only colorize different significant digits (no coloring at all the last line in this cases) since the aim is to highlight the **numerical** difference magnitude.

In that case I would recommend using something other than a textual difference. My preference goes to the work by D. Stott Parker, especially the definition of the “number of (absolute) significant digits” introduced in his “\frac 1 2 ulsp algorithm”:

```julia
using PrettyTables, Crayons, Printf

function highlight_different_digits(a, b)
    # Stott Parker's definition of the "number of (absolute)
    # significant digits" of `b` seen as an approximation of `a`.
    s = -log10(2*abs(b-a)/10.0^(1+floor(log10(abs(a)))))

    j = floor(Int, min(s, 100))
    j > 0 && (j+=1) # account for the dot in 2nd place in scientific notation

    a_str = @sprintf "%.10e" a
    b_str = @sprintf "%.10e" b
    j = clamp(j, 0, lastindex(b_str))

    common = SubString(b_str, 1, j)
    different = SubString(b_str, j+1)
    red = crayon"red bold"
    b_str = AnsiTextCell("$common$red$different")
    [a_str, b_str]
end

```

```julia
# Random test data
n = 10
x = rand(n)
y = x .+ 2e-3 .* (rand(n) .- 0.5)

# Corner cases
y[1] = x[1]
x[end], y[end] = (0.1, 0.099998)

table = reduce(vcat, permutedims(highlight_different_digits(x[i], y[i])) for i in eachindex(x))
pretty_table(table, header=["Reference value", "Approximation"])

```

 ![Screenshot from 2023-01-09 20-18-56](https://global.discourse-cdn.com/julialang/original/3X/1/f/1f4e75eaba9bc5e053ea429ff349cb3870219509.png)

  

* * *

Ref: Douglas Stott Parker, “Monte Carlo Arithmetic : exploiting randomness in floating-point arithmetic”, 1997 (pages 19-20).

---

<div class="post-metadata">

**Author:** ![LaurentPlagne](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laurentplagne/32/10103_2.png) [@LaurentPlagne](https://discourse.julialang.org/u/LaurentPlagne)\
**Post date:** [January 9, 2023, 7:52pm UTC](https://discourse.julialang.org/t/prettytables-diff-digits-highlight/92664/10 "2023-01-09T19:52:07Z")

</div>

Super cool and mathematically grounded ! Big Thx !  
I will avoid coloring the exponent part `e-xy` but appart from that it is perfect for my need !

Additional question : what if a is zero ?
