|
| 1 | +open Bechamel |
| 2 | + |
| 3 | +let pad width v = |
| 4 | + let padding = String.make (width - String.length v) ' ' in |
| 5 | + padding ^ v |
| 6 | + |
| 7 | +let pp_row ~width f data = |
| 8 | + data |> List.iteri (fun i v -> |
| 9 | + if i > 0 then Fmt.comma f (); |
| 10 | + Fmt.pf f "%s" (pad width.(i) v) |
| 11 | + ) |
| 12 | + |
| 13 | +let pp f results = |
| 14 | + let results = Hashtbl.to_seq results |> Array.of_seq in |
| 15 | + Array.sort (fun (n1, _) (n2, _) -> String.compare n1 n2) results; (* Sort columns *) |
| 16 | + let rows = snd results.(0) |> Hashtbl.to_seq |> Seq.map fst |> Array.of_seq in |
| 17 | + let width = Array.make (Array.length results + 1) 0 in |
| 18 | + width.(0) <- String.length "name, "; |
| 19 | + results |> Array.iteri (fun i (name, _) -> width.(i + 1) <- String.length name + 2); |
| 20 | + Array.sort String.compare rows; |
| 21 | + let rows = |
| 22 | + rows |> Array.map (fun name -> |
| 23 | + width.(0) <- max width.(0) (String.length name + 2); |
| 24 | + let values = |
| 25 | + results |> Array.mapi (fun i (_, col) -> |
| 26 | + let v = |
| 27 | + match Hashtbl.find col name |> Analyze.OLS.estimates with |
| 28 | + | Some [v] -> Printf.sprintf "%f" v |
| 29 | + | _ -> assert false |
| 30 | + in |
| 31 | + width.(i + 1) <- max width.(i + 1) (String.length v + 2); |
| 32 | + v |
| 33 | + ) |
| 34 | + in |
| 35 | + name, values |
| 36 | + ) |
| 37 | + in |
| 38 | + let metrics = Array.to_list results |> List.map fst in |
| 39 | + let headings = List.mapi (fun i v -> pad width.(i) v) ("name" :: metrics) in |
| 40 | + Fmt.pf f "@[<v>@[<h>%a@]" Fmt.(list ~sep:comma string) headings; |
| 41 | + rows |> Array.iter (fun (name, data) -> |
| 42 | + Fmt.pf f "@,@[<h>%a@]" (pp_row ~width) (name :: Array.to_list data); |
| 43 | + ); |
| 44 | + Fmt.pf f "@]" |
0 commit comments