I want to be able to pass a sequence of option float
to the RProvider in F#
. If I have a sequence of floats with Some float
and None
, how can I get the None
values into R
with the RProvider
? I would have expected the None
s would be equivalent to an NA
value in R
, but I can't get pass a seq<option float>
to R.
For example, with
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
I get a multi-line error:
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
The only way I can pass anything to the RProvider
is if I convert the seq<option float>
to a seq<float>
with
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
but this negates the purpose of having the option of None (which, I would have thought would be comparable to R
s NA
value.
How can I pass a sequence of values to the RProvider
where some of the values are None
in F#
and should be NA
in R
?
You can do it with Deedle and nullable values:
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
I think you should be able to do this just be replacing the None
values with nan
(this is not entirely right, because in R NA
and NaN
are different, but there is no way to express two different non-values for a float in 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
I have not tested this, but I think this is what we do in Deedle internally.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.