Fagui Curtain
Fagui Curtain

Reputation: 1917

Working with missing values in Deedle Time Series in F# (3)

This is another follow-up to Working with missing values in Deedle Time Series in F# (2)

I have written this function to map2 series, returning a missing value when either input is missing.

let map2series (f:'T1->'T2->'R)(series1:Series<'K,'T1 opt>)(series2:Series<'K,'T2 opt>):Series<'K,'R opt>=
     let S = series1.Zip(series2,JoinKind.Outer) //Series<'K,('T1 opt opt * 'T2 opt opt)>

     S |> Series.mapValues (fun (a,b) -> match (a,b) with 
                                          | (OptionalValue.Present(a'), OptionalValue.Present(b')) -> OptionalValue.map2 f a' b'
                                          | _ -> OptionalValue.Missing)

since Series<'K,'T opt> appear naturally in Deedle after using .Zip or .Join methods.

However, as seen previously, Series<'K,'V> already supports missing values, so I'd like to rewrite the function above that basically would do the same except that it takes Series<'K,'V> as inputs

let map2series1 (f:'T1->'T2->'R)(series1:Series<'K,'T1>)(series2:Series<'K,'T2>):Series<'K,'R>=
     let S = series1.Zip(series2,JoinKind.Outer) //Series<'K,('T1 opt * 'T2 opt)>
     S |> Series.mapValues (fun (a,b) -> match (a,b) with 
                                          | (OptionalValue.Present(a'), OptionalValue.Present(b')) -> f a' b'
                                          | _ -> None)

However this doesn't work, i don't have the right syntax in the second union case when one value is missing...

basically instead of the last None, i need to assign a value which corresponds to <missing> but i can't find it.

I also looked at something like Option.bind OptionalValue.asOption OptionalValue.Missing but cannot find the right expression

Upvotes: 3

Views: 124

Answers (1)

FoggyFinder
FoggyFinder

Reputation: 2220

You can do it this way:

let map2 f =
    function
    | OptionalValue.Present(a'), OptionalValue.Present(b') -> Some (f a' b')
    | _ -> None

let map2series f series1 series2 =
     series2
     |> Series.zip series1
     |> Series.mapAll(fun _ -> Option.bind(map2 f)) 

Upvotes: 1

Related Questions