Search code examples
f#deedle

A straightforward functional way to rename columns of a Deedle data frame


Is there a concise functional way to rename columns of a Deedle data frame f?

f.RenameColumns(...) is usable, but mutates the data frame it is applied to, so it's a bit of a pain to make the renaming operation idempotent. I have something like f.RenameColumns (fun c -> ( if c.IndexOf( "_" ) < 0 then c else c.Substring( 0, c.IndexOf( "_" ) ) ) + "_renamed"), which is ugly.

What would be nice is something that creates a new frame from the input frame, like this: Frame( f |> Frame.cols |> Series.keys |> Seq.map someRenamingFunction, f |> Frame.cols |> Series.values ) but this gets tripped up by the second part -- the type of f |> Frame.cols |> Series.values is not what is required by the Frame constructor.

How can I concisely transform f |> Frame.cols |> Series.values so that its result is edible by the Frame constructor?


Solution

  • You can determine its function when used with RenameColumns:

    df.RenameColumns someRenamingFunction
    

    You can also use the function Frame.mapColKeys.

    Builds a new data frame whose columns are the results of applying the specified function on the columns of the input data frame. The function is called with the column key and object series that represents the column data. Source

    Example:

    type Record = {Name:string; ID:int ; Amount:int}
    
    let data = 
        [| 
            {Name = "Joe";     ID = 51; Amount = 50};    
            {Name = "Tomas";   ID = 52; Amount = 100};  
            {Name = "Eve";     ID = 65; Amount = 20};   
        |]
    
    let df = Frame.ofRecords data
    
    let someRenamingFunction s =
        sprintf "%s(%i)" s s.Length
    
    df.Format() |> printfn "%s"
    
    let ndf = df |> Frame.mapColKeys someRenamingFunction
    
    ndf.Format() |> printfn "%s"
    
    df.RenameColumns someRenamingFunction
    
    df.Format() |> printfn "%s"
    

    Print:

         Name  ID Amount
    0 -> Joe   51 50
    1 -> Tomas 52 100
    2 -> Eve   65 20
    
         Name(4) ID(2) Amount(6)
    0 -> Joe     51    50
    1 -> Tomas   52    100
    2 -> Eve     65    20
    
         Name(4) ID(2) Amount(6)
    0 -> Joe     51    50
    1 -> Tomas   52    100
    2 -> Eve     65    20