2016-09-02 33 views
1

我希望能夠將option float的序列傳遞給F#中的RProvider。如果我有一個帶有Some floatNone的花車序列,如何將None值與RProvider一起變爲R?我本來期望的None s就相當於RNA價值,但我不能讓傳遞seq<option float>到R.將F#中的seq <float option>傳遞給RProvider

例如,

open System 
open RDotNet 
open RProvider 
open RProvider.graphics 
open RProvider.stats 

let optData4 = 
    seq [Some 10.0; Some 9.0; Some 8.0; None; Some 6.0; 
     Some 5.0; Some 5.0; None; Some 4.0; Some 2.0; 
     None] 

let testData4 = 
    namedParams [ 
     "regPrice", optData4;] 
    |> R.data_frame 

,我收到了多直插式的錯誤:

System.Exception: No converter registered for type Microsoft.FSharp.Collections.FSharpList`1[[Microsoft.FSharp.Core.FSharpOption`1[[System.Double, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], FSharp.Core, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]] or any of its base types 
> at [email protected](String message) in C:\Tomas\Public\bmc\FSharp.RProvider\src\RProvider\RInterop.fs:line 164 
    at RProvider.RInteropInternal.REngine.SetValue(REngine this, Object value, FSharpOption`1 symbolName) in C:\Tomas\Public\bmc\FSharp.RProvider\src\RProvider\RInterop.fs:line 274 
    at RProvider.RInteropInternal.toR(Object value) in C:\Tomas\Public\bmc\FSharp.RProvider\src\RProvider\RInterop.fs:line 287 
    at [email protected](List`1 tempSymbols, Object arg) in C:\Tomas\Public\bmc\FSharp.RProvider\src\RProvider\RInterop.fs:line 461 
    at [email protected](IEnumerable`1& next) in C:\Tomas\Public\bmc\FSharp.RProvider\src\RProvider\RInterop.fs:line 469 
    at Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1.MoveNextImpl() 
    at Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1.System-Collections-IEnumerator-MoveNext() 
    at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) 
    at Microsoft.FSharp.Collections.SeqModule.ToArray[T](IEnumerable`1 source) 
    at RProvider.RInterop.callFunc(String packageName, String funcName, IEnumerable`1 argsByName, Object[] varArgs) in C:\Tomas\Public\bmc\FSharp.RProvider\src\RProvider\RInterop.fs:line 466 
    at <StartupCode$FSI_0012>[email protected]() in C:\Users\sranney\repositories\carolina_refit_bits\refit_bits\refit_bits\RDemo.fs:line 102 
Stopped due to error 

我可以通過什麼的RProvider的唯一方法是,如果我轉換seq<option float>seq<float>

let optData4 = 
    seq [Some 10.0; Some 9.0; Some 8.0; None; Some 6.0; 
     Some 5.0; Some 5.0; None; Some 4.0; Some 2.0; 
     None] 
    |> Seq.choose id 

let testData4 = 
    namedParams [ 
     "regPrice", optData4;] 
    |> R.data_frame 

但這否定了有沒有的選項(這,我還以爲是堪比R小號NA價值的目的。

我怎麼能值傳遞給RProvider序列,其中一些值是F#None並應在RNA

+0

我絕對沒有F#的知識,但是在R中,NA是一個超類,它包含了每個模式的其他邏輯的特定NA值。如果順序與「浮動」,那麼你可能需要返回'NA_real_' –

回答

3

我想你應該能夠做到這一點正好與nan取代None值(這並不完全正確,因爲R中NANaN是不同的,但沒有辦法表達對在F#的浮動兩種不同的非值):

let optData4 = 
    [ 10.0; 9.0; 8.0; nan; 6.0; 5.0; 5.0; nan; 4.0; 2.0; nan ] 

let testData4 = 
    namedParams [ 
     "regPrice", optData4;] 
    |> R.data_frame 

我沒有測試過這一點,但我認爲這是我們在做Deedle內部。

+2

工作很好。我用一個簡單的函數轉換爲值/ nana:'let toNan x = match x with |一些x - > x |沒有 - > nan',並把所有東西都傳遞給'R'。 – Steven

3

您可以Deedle和空的值做到這一點:

let toNullable = 
     function 
     | None -> Nullable() 
     | Some x -> Nullable(x) 

let optData4 = 
    seq [Some 10.0; Some 9.0; Some 8.0; None; Some 6.0; 
     Some 5.0; Some 5.0; None; Some 4.0; Some 2.0; 
     None] 
    |> Seq.map(toNullable) 

let series = Series.ofNullables(optData4) 

let testData4 = 
    namedParams [ 
     "regPrice", series;] 
    |> R.data_frame 
+1

'Option.toNullable'內置於F#4.0及更高版本,因此不需要定義自己的版本。 –