I need to sort the columns of a Deedle data frame based on the value of the last row. So the first column would have the largest value and the last column would have the smallest value in the last row. Deedle's Frame has most of its functionality on rows.
Here is some code to generate sample data where Item2 will end up with a value larger than Item1:
#load @"..\..\FSLAB\packages\FsLab\FsLab.fsx"
open System
open System.Drawing
open System.Windows.Forms
open Deedle
open FSharp.Charting
open FSharp.Charting.ChartTypes
let rnd = new System.Random()
let dateRange = [for i in 9..-1..0 -> DateTime.Today.AddDays(float -i)]
let makeData x = [for i in 0..x-2 -> rnd.NextDouble()-0.5] |> List.scan (+) 0.
let series = makeData 10 |> List.zip <| (makeData 10 |> List.map (fun x -> x + 1.))
let df = series |> Frame.ofRecords
df?DateIndex <- dateRange |> Series.ofValues
let df = df.IndexRows<DateTime>("DateIndex")
In this case the last row of Frame will look like this, having the larger of the values in the second column:
2016/05/14 0:00:00 -> 0.143158562780897 0.918480403450541
But I would like to have it in this order:
2016/05/14 0:00:00 -> 0.918480403450541 0.143158562780897
I posted an answer but would like to see if there are other approaches as I'm not yet too familiar with Deedle.
Frame.sortRowsWith needs a sorting function:
let reverser (a:float) (b:float) =
if a > b then
-1
else if a < b then
1
else
0
let df1 = df |> Frame.transpose
let coldIdx = df1.ColumnKeys |> Seq.max
Frame.sortRowsWith coldIdx reverser df1 |> Frame.transpose
So it transposes the data Frame, then gets the index of the last row (column in this case) and sorts the columns from the largest to smallest, finally transposing it back. This is handy for charting because this way the chart legends will line up with the series in the chart.