将一个seq <float option =“”>从F#传递给RProvider

时间:2016-09-02 02:33:26

标签: r f#

我希望能够将option float的序列传递给F#中的RProvider。如果我有一系列包含Some floatNone的浮点数,如何将None值与R一起转换为RProvider?我原以为None s相当于NA中的R值,但我无法将seq<option float>传递给R。

例如,使用

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 RProvider.RInteropInternal.convertToR@164.Invoke(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 RProvider.RInterop.passArg@447(List`1 tempSymbols, Object arg) in C:\Tomas\Public\bmc\FSharp.RProvider\src\RProvider\RInterop.fs:line 461
   at RProvider.RInterop.argList@468-1.GenerateNext(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>.$FSI_0012.main@() 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

但这否定了选择None的目的(我认为这与R NA值相当。

如何将一系列值传递给RProvider,其中None中的某些值为F#NA中应为R

2 个答案:

答案 0 :(得分: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 :(得分:3)

我认为您应该能够将<?xml version="1.0" encoding="UTF-8"?> <ns0:Document xmlns:info="urn:swift:xsd:appInfo" xmlns:ns0="urn:swift:xsd:fin.760.2016" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:swift:xsd:fin.760.2016 swift.xsd"> <ns0:MT760> <ns0:F27a> <ns0:F27> <ns0:Number>0</ns0:Number> <ns0:Total>0</ns0:Total> </ns0:F27> </ns0:F27a> <ns0:F20a> <ns0:F20>F200</ns0:F20> </ns0:F20a> <ns0:F23a> <ns0:F23>F230</ns0:F23> </ns0:F23a> <ns0:F40a> <ns0:F40C> <ns0:Type>ISPR</ns0:Type> </ns0:F40C> </ns0:F40a> <ns0:F77a> <ns0:F77C> <ns0:Narrative> <ns0:Line>Line0</ns0:Line> <ns0:Line>Line1</ns0:Line> </ns0:Narrative> </ns0:F77C> </ns0:F77a> </ns0:MT760> </ns0:Document> 值替换为None(这不完全正确,因为在R nanNA中不同,但没有办法在F#中为浮点表达两个不同的非值:

NaN

我没有对此进行过测试,但我认为这就是我们在Deedle内部所做的事情。