This tutorial demonstrates how to use the R type provider in an F# script. You
can also use the R type provider in other scenarios such as apps and libraries.
Make sure you have set up your system as specified here.
First, make a new F# script (e.g., sample.fsx). In your new script, first load
the R type provider from the NuGet package repository.
#r "nuget:RProvider"
For this tutorial, we use open
to reference a number of packages
including stats
, tseries
and zoo
:
open RProvider
open RProvider.graphics
open RProvider.stats
open RProvider.tseries
open RProvider.zoo
open System
open System.Net.Http
If either of the namespaces above are unrecognized, you need to install the package in R
using install.packages("stats")
.
Add this line to your script to tell F# interactive how to print out
the values of R objects:
fsi.AddPrinter FSIPrinters.rValue
In this tutorial, we use F# Data to access stock
prices from the Yahoo Finance portal. For more information, see the documentation for the
CSV type provider.
The following snippet defines a function getStockPrices
that returns
array with prices for the specified stock and a specified number of days from a stocks API:
// NB The 'demo' key has very limited usage.
let apiKey = "demo"
// URL of a service that generates price data
let url stock = sprintf "https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=%s&apikey=%s&datatype=csv" stock apiKey
/// Returns prices (as tuple) of a given stock
let getStockPrices stock count =
// Download the data and split it into lines
use wc = new HttpClient()
let data = wc.GetStringAsync(url stock) |> Async.AwaitTask |> Async.RunSynchronously
let dataLines = data.Split([| '\n' |], StringSplitOptions.RemoveEmptyEntries)
// Parse lines of the CSV file and take specified
// number of days using in the oldest to newest order
seq { for line in dataLines |> Seq.skip 1 do
let infos = line.Split(',')
yield float infos.[4] }
|> Seq.truncate count |> Array.ofSeq |> Array.rev
/// Get opening prices for MSFT for the last 100 days
let msftOpens: float[] = getStockPrices "MSFT" 100
Now, we're ready to call R functions using the type provider. The following snippet takes
msftOpens
, calculates logarithm of the values using R.log
and then calculates the
differences of the resulting vector using R.diff
:
// Retrieve stock price time series and compute returns
let msft = msftOpens |> R.log |> R.diff
If you want to see the resulting values, you can call msft.AsVector()
in F# Interactive.
Next, we use the acf
function to display the atuo-correlation and call adf_test
to
see if the msft
returns are stationary/non-unit root:
let a = R.acf(msft)
let adf = R.adf_test(msft)
After running the first snippet, a window similar to the following should appear (note that
it might not appear as a top-most window).
Finally, we can obtain data for multiple different indicators and use the R.pairs
function
to produce a matrix of scatter plots:
// Build a list of tickers and get diff of logs of prices for each one
let tickers =
[ "MSFT"; "AAPL"; "X"; "VXX"; "SPX"; "GLD" ]
let data =
[ for t in tickers ->
printfn "got one!"
t, getStockPrices t 255 |> R.log |> R.diff ]
// Create an R data frame with the data and call 'R.pairs'
let df = R.data_frame(namedParams data)
R.pairs(df)
As a result, you should see a window showing results similar to these:
namespace RProvider
Multiple items
namespace RProvider
--------------------
type RProvider =
inherit TypeProviderForNamespaces
new : cfg:TypeProviderConfig -> RProvider
--------------------
new : cfg:CompilerServices.TypeProviderConfig -> RProvider
namespace RProvider.graphics
namespace RProvider.stats
namespace RProvider.tseries
namespace RProvider.zoo
namespace System
namespace System.Net
namespace System.Net.Http
module FSIPrinters
from RProvider
<summary>
Print functions that may be used in
F# interactive to 'pretty-print' R types to the
console window. Use in your scripts by
passing to `fsi.AddPrinter`.
</summary>
val rValue : synexpr:RDotNet.SymbolicExpression -> string
<summary>
Print any `SymbolicExpression` using R's built-in
`print` function.
</summary>
val apiKey : string
val url : stock:string -> string
val stock : string
val sprintf : format:Printf.StringFormat<'T> -> 'T
<summary>Print to a string using the given format.</summary>
<param name="format">The formatter.</param>
<returns>The formatted result.</returns>
val getStockPrices : stock:string -> count:int -> float []
Returns prices (as tuple) of a given stock
val count : int
val wc : HttpClient
Multiple items
type HttpClient =
inherit HttpMessageInvoker
new : unit -> unit + 2 overloads
member CancelPendingRequests : unit -> unit
member DeleteAsync : requestUri: string -> Task<HttpResponseMessage> + 3 overloads
member Dispose : disposing: bool -> unit
member GetAsync : requestUri: string -> Task<HttpResponseMessage> + 7 overloads
member GetByteArrayAsync : requestUri: string -> Task<byte []> + 3 overloads
member GetStreamAsync : requestUri: string -> Task<Stream> + 3 overloads
member GetStringAsync : requestUri: string -> Task<string> + 3 overloads
member PatchAsync : requestUri: string * content: HttpContent -> Task<HttpResponseMessage> + 3 overloads
...
<summary>Provides a class for sending HTTP requests and receiving HTTP responses from a resource identified by a URI.</summary>
--------------------
HttpClient() : HttpClient
HttpClient(handler: HttpMessageHandler) : HttpClient
HttpClient(handler: HttpMessageHandler, disposeHandler: bool) : HttpClient
val data : string
HttpClient.GetStringAsync(requestUri: Uri) : Threading.Tasks.Task<string>
HttpClient.GetStringAsync(requestUri: string) : Threading.Tasks.Task<string>
HttpClient.GetStringAsync(requestUri: Uri, cancellationToken: Threading.CancellationToken) : Threading.Tasks.Task<string>
HttpClient.GetStringAsync(requestUri: string, cancellationToken: Threading.CancellationToken) : Threading.Tasks.Task<string>
Multiple items
type Async =
static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)
static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)
static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool>
static member AwaitTask : task:Task<'T> -> Async<'T> + 1 overload
static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool>
static member CancelDefaultToken : unit -> unit
static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
static member Choice : computations:seq<Async<'T option>> -> Async<'T option>
static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T> + 3 overloads
static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T>
...
<summary>Holds static members for creating and manipulating asynchronous computations.</summary>
<remarks>
See also <a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/asynchronous-workflows">F# Language Guide - Async Workflows</a>.
</remarks>
<category index="1">Async Programming</category>
--------------------
type Async<'T> =
<summary>
An asynchronous computation, which, when run, will eventually produce a value of type T, or else raises an exception.
</summary>
<remarks>
This type has no members. Asynchronous computations are normally specified either by using an async expression
or the static methods in the <see cref="T:Microsoft.FSharp.Control.Async" /> type.
See also <a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/asynchronous-workflows">F# Language Guide - Async Workflows</a>.
</remarks>
<namespacedoc><summary>
Library functionality for asynchronous programming, events and agents. See also
<a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/asynchronous-workflows">Asynchronous Programming</a>,
<a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/members/events">Events</a> and
<a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/lazy-expressions">Lazy Expressions</a> in the
F# Language Guide.
</summary></namespacedoc>
<category index="1">Async Programming</category>
static member Async.AwaitTask : task:Threading.Tasks.Task -> Async<unit>
static member Async.AwaitTask : task:Threading.Tasks.Task<'T> -> Async<'T>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:Threading.CancellationToken -> 'T
val dataLines : string []
String.Split([<ParamArray>] separator: char []) : string []
String.Split(separator: string [], options: StringSplitOptions) : string []
String.Split(separator: string,?options: StringSplitOptions) : string []
String.Split(separator: char [], options: StringSplitOptions) : string []
String.Split(separator: char [], count: int) : string []
String.Split(separator: char,?options: StringSplitOptions) : string []
String.Split(separator: string [], count: int, options: StringSplitOptions) : string []
String.Split(separator: string, count: int,?options: StringSplitOptions) : string []
String.Split(separator: char [], count: int, options: StringSplitOptions) : string []
String.Split(separator: char, count: int,?options: StringSplitOptions) : string []
type StringSplitOptions =
| None = 0
| RemoveEmptyEntries = 1
| TrimEntries = 2
<summary>Specifies options for applicable <see cref="Overload:System.String.Split" /> method overloads, such as whether to omit empty substrings from the returned array or trim whitespace from substrings.</summary>
field StringSplitOptions.RemoveEmptyEntries: StringSplitOptions = 1
<summary><para>Omit array elements that contain an empty string from the result.</para><para>If <see cref="F:System.StringSplitOptions.RemoveEmptyEntries" /> and <see cref="F:System.StringSplitOptions.TrimEntries" /> are specified together, then substrings that consist only of white-space characters are also removed from the result.</para></summary>
Multiple items
val seq : sequence:seq<'T> -> seq<'T>
<summary>Builds a sequence using sequence expression syntax</summary>
<param name="sequence">The input sequence.</param>
<returns>The result sequence.</returns>
--------------------
type seq<'T> = Collections.Generic.IEnumerable<'T>
<summary>An abbreviation for the CLI type <see cref="T:System.Collections.Generic.IEnumerable`1" /></summary>
<remarks>
See the <see cref="T:Microsoft.FSharp.Collections.SeqModule" /> module for further operations related to sequences.
See also <a href="https://docs.microsoft.com/dotnet/fsharp/language-reference/sequences">F# Language Guide - Sequences</a>.
</remarks>
val line : string
module Seq
from Microsoft.FSharp.Collections
<summary>Contains operations for working with values of type <see cref="T:Microsoft.FSharp.Collections.seq`1" />.</summary>
val skip : count:int -> source:seq<'T> -> seq<'T>
<summary>Returns a sequence that skips N elements of the underlying sequence and then yields the
remaining elements of the sequence.</summary>
<param name="count">The number of items to skip.</param>
<param name="source">The input sequence.</param>
<returns>The result sequence.</returns>
<exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
<exception cref="T:System.InvalidOperationException">Thrown when count exceeds the number of elements
in the sequence.</exception>
val infos : string []
Multiple items
val float : value:'T -> float (requires member op_Explicit)
<summary>Converts the argument to 64-bit float. This is a direct conversion for all
primitive numeric types. For strings, the input is converted using <c>Double.Parse()</c>
with InvariantCulture settings. Otherwise the operation requires an appropriate
static conversion method on the input type.</summary>
<param name="value">The input value.</param>
<returns>The converted float</returns>
--------------------
[<Struct>]
type float = Double
<summary>An abbreviation for the CLI type <see cref="T:System.Double" />.</summary>
<category>Basic Types</category>
--------------------
type float<'Measure> =
float
<summary>The type of double-precision floating point numbers, annotated with a unit of measure.
The unit of measure is erased in compiled code and when values of this type
are analyzed using reflection. The type is representationally equivalent to
<see cref="T:System.Double" />.</summary>
<category index="6">Basic Types with Units of Measure</category>
val truncate : count:int -> source:seq<'T> -> seq<'T>
<summary>Returns a sequence that when enumerated returns at most N elements.</summary>
<param name="count">The maximum number of items to enumerate.</param>
<param name="source">The input sequence.</param>
<returns>The result sequence.</returns>
<exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
type Array =
interface ICollection
interface IEnumerable
interface IList
interface IStructuralComparable
interface IStructuralEquatable
interface ICloneable
new : unit -> unit
member Clone : unit -> obj
member CopyTo : array: Array * index: int -> unit + 1 overload
member GetEnumerator : unit -> IEnumerator
...
<summary>Provides methods for creating, manipulating, searching, and sorting arrays, thereby serving as the base class for all arrays in the common language runtime.</summary>
val ofSeq : source:seq<'T> -> 'T []
<summary>Builds a new array from the given enumerable object.</summary>
<param name="source">The input sequence.</param>
<returns>The array of elements from the sequence.</returns>
<exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
val rev : array:'T [] -> 'T []
<summary>Returns a new array with the elements in reverse order.</summary>
<param name="array">The input array.</param>
<returns>The reversed array.</returns>
<exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
val msftOpens : float []
Get opening prices for MSFT for the last 100 days
val msft : RDotNet.SymbolicExpression
type R =
static member ! :?paramArray: obj [] -> SymbolicExpression + 2 overloads
static member != :?paramArray: obj [] -> SymbolicExpression + 2 overloads
static member !_hexmode :?a: obj -> SymbolicExpression + 2 overloads
static member !_octmode :?a: obj -> SymbolicExpression + 2 overloads
static member $ :?paramArray: obj [] -> SymbolicExpression + 2 overloads
static member $<- :?paramArray: obj [] -> SymbolicExpression + 2 overloads
static member $<-_data_frame :?x: obj *?name: obj *?value: obj -> SymbolicExpression + 2 overloads
static member $_DLLInfo :?x: obj *?name: obj -> SymbolicExpression + 2 overloads
static member $_package__version :?x: obj *?name: obj -> SymbolicExpression + 2 overloads
static member %% :?paramArray: obj [] -> SymbolicExpression + 2 overloads
...
Base R functions.
R.log(paramsByName: List<string * obj>) : RDotNet.SymbolicExpression
R.log(paramsByName: Collections.Generic.IDictionary<string,obj>) : RDotNet.SymbolicExpression
R.log(?paramArray: obj []) : RDotNet.SymbolicExpression
Logarithms and Exponentials
R.diff(paramsByName: List<string * obj>) : RDotNet.SymbolicExpression
R.diff(paramsByName: Collections.Generic.IDictionary<string,obj>) : RDotNet.SymbolicExpression
R.diff(?x: obj,?___: obj,?paramArray: obj []) : RDotNet.SymbolicExpression
Lagged Differences
val a : RDotNet.SymbolicExpression
type R =
static member AIC :?object: obj *?___: obj *?k: obj *?paramArray: obj [] -> SymbolicExpression + 2 overloads
static member ARMAacf :?ar: obj *?ma: obj *?lag_max: obj *?pacf: obj -> SymbolicExpression + 2 overloads
static member ARMAtoMA :?ar: obj *?ma: obj *?lag_max: obj -> SymbolicExpression + 2 overloads
static member BIC :?object: obj *?___: obj *?paramArray: obj [] -> SymbolicExpression + 2 overloads
static member Box_test :?x: obj *?lag: obj *?type: obj *?fitdf: obj -> SymbolicExpression + 2 overloads
static member C :?object: obj *?contr: obj *?how_many: obj *?___: obj *?paramArray: obj [] -> SymbolicExpression + 2 overloads
static member D :?expr: obj *?name: obj -> SymbolicExpression + 2 overloads
static member DF2formula :?x: obj *?env: obj -> SymbolicExpression + 2 overloads
static member Gamma :?link: obj -> SymbolicExpression + 2 overloads
static member HoltWinters :?x: obj *?alpha: obj *?beta: obj *?gamma: obj *?seasonal: obj *?start_periods: obj *?l_start: obj *?b_start: obj *?s_start: obj *?optim_start: obj *?optim_control: obj -> SymbolicExpression + 2 overloads
...
R statistical functions.
R.acf(paramsByName: List<string * obj>) : RDotNet.SymbolicExpression
R.acf(paramsByName: Collections.Generic.IDictionary<string,obj>) : RDotNet.SymbolicExpression
R.acf(?x: obj,?lag_max: obj,?type: obj,?plot: obj,?na_action: obj,?demean: obj,?___: obj,?paramArray: obj []) : RDotNet.SymbolicExpression
Auto- and Cross- Covariance and -Correlation Function Estimation
val adf : RDotNet.SymbolicExpression
type R =
static member adf_test :?x: obj *?alternative: obj *?k: obj -> SymbolicExpression + 2 overloads
static member approx_irts :?object: obj *?time: obj *?___: obj *?paramArray: obj [] -> SymbolicExpression + 2 overloads
static member arma :?x: obj *?order: obj *?lag: obj *?coef: obj *?include_intercept: obj *?series: obj *?qr_tol: obj *?___: obj *?paramArray: obj [] -> SymbolicExpression + 2 overloads
static member as_irts :?object: obj -> SymbolicExpression + 2 overloads
static member bds_test :?x: obj *?m: obj *?eps: obj *?trace: obj -> SymbolicExpression + 2 overloads
static member daysecond :?object: obj *?tz: obj -> SymbolicExpression + 2 overloads
static member garch :?x: obj *?order: obj *?series: obj *?control: obj *?___: obj *?paramArray: obj [] -> SymbolicExpression + 2 overloads
static member garch_control :?maxiter: obj *?trace: obj *?start: obj *?grad: obj *?abstol: obj *?reltol: obj *?xtol: obj *?falsetol: obj *?___: obj *?paramArray: obj [] -> SymbolicExpression + 2 overloads
static member get_hist_quote :?instrument: obj *?start: obj *?end: obj *?quote: obj *?provider: obj *?method: obj *?origin: obj *?compression: obj *?retclass: obj *?quiet: obj *?drop: obj -> SymbolicExpression + 2 overloads
static member irts :?time: obj *?value: obj -> SymbolicExpression + 2 overloads
...
Time series analysis and computational finance.
R.adf_test(paramsByName: List<string * obj>) : RDotNet.SymbolicExpression
R.adf_test(paramsByName: Collections.Generic.IDictionary<string,obj>) : RDotNet.SymbolicExpression
R.adf_test(?x: obj,?alternative: obj,?k: obj) : RDotNet.SymbolicExpression
Augmented Dickey-Fuller Test
val tickers : string list
val data : (string * RDotNet.SymbolicExpression) list
val t : string
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
<summary>Print to <c>stdout</c> using the given format, and add a newline.</summary>
<param name="format">The formatter.</param>
<returns>The formatted result.</returns>
val df : RDotNet.SymbolicExpression
R.data_frame(paramsByName: List<string * obj>) : RDotNet.SymbolicExpression
R.data_frame(paramsByName: Collections.Generic.IDictionary<string,obj>) : RDotNet.SymbolicExpression
R.data_frame(?___: obj,?row_names: obj,?check_rows: obj,?check_names: obj,?fix_empty_names: obj,?stringsAsFactors: obj,?paramArray: obj []) : RDotNet.SymbolicExpression
Data Frames
val namedParams : s:seq<string * 'a> -> Collections.Generic.IDictionary<string,obj>
<summary>
Construct a dictionary of named params to pass to an R function.
## Example
For example, if you want to call the `R.plot` function with named parameters
specifying `x`, `type`, `col` and `ylim`, you can use the following:
[ "x", box widgets;
"type", box "o";
"col", box "blue";
"ylim", box [0; 25] ]
|> namedParams |> R.plot
</summary>
type R =
static member Axis :?x: obj *?at: obj *?___: obj *?side: obj *?labels: obj *?paramArray: obj [] -> SymbolicExpression + 2 overloads
static member abline :?a: obj *?b: obj *?h: obj *?v: obj *?reg: obj *?coef: obj *?untf: obj *?___: obj *?paramArray: obj [] -> SymbolicExpression + 2 overloads
static member arrows :?x0: obj *?y0: obj *?x1: obj *?y1: obj *?length: obj *?angle: obj *?code: obj *?col: obj *?lty: obj *?lwd: obj *?___: obj *?paramArray: obj [] -> SymbolicExpression + 2 overloads
static member assocplot :?x: obj *?col: obj *?space: obj *?main: obj *?xlab: obj *?ylab: obj -> SymbolicExpression + 2 overloads
static member axTicks :?side: obj *?axp: obj *?usr: obj *?log: obj *?nintLog: obj -> SymbolicExpression + 2 overloads
static member axis :?side: obj *?at: obj *?labels: obj *?tick: obj *?line: obj *?pos: obj *?outer: obj *?font: obj *?lty: obj *?lwd: obj *?lwd_ticks: obj *?col: obj *?col_ticks: obj *?hadj: obj *?padj: obj *?gap_axis: obj *?___: obj *?paramArray: obj [] -> SymbolicExpression + 2 overloads
static member axis_Date :?side: obj *?x: obj *?at: obj *?format: obj *?labels: obj *?___: obj *?paramArray: obj [] -> SymbolicExpression + 2 overloads
static member axis_POSIXct :?side: obj *?x: obj *?at: obj *?format: obj *?labels: obj *?___: obj *?paramArray: obj [] -> SymbolicExpression + 2 overloads
static member barplot :?height: obj *?___: obj *?paramArray: obj [] -> SymbolicExpression + 2 overloads
static member barplot_default :?height: obj *?width: obj *?space: obj *?names_arg: obj *?legend_text: obj *?beside: obj *?horiz: obj *?density: obj *?angle: obj *?col: obj *?border: obj *?main: obj *?sub: obj *?xlab: obj *?ylab: obj *?xlim: obj *?ylim: obj *?xpd: obj *?log: obj *?axes: obj *?axisnames: obj *?cex_axis: obj *?cex_names: obj *?inside: obj *?plot: obj *?axis_lty: obj *?offset: obj *?add: obj *?ann: obj *?args_legend: obj *?___: obj *?paramArray: obj [] -> SymbolicExpression + 2 overloads
...
R functions for base graphics.
R.pairs(paramsByName: List<string * obj>) : RDotNet.SymbolicExpression
R.pairs(paramsByName: Collections.Generic.IDictionary<string,obj>) : RDotNet.SymbolicExpression
R.pairs(?x: obj,?___: obj,?paramArray: obj []) : RDotNet.SymbolicExpression
Scatterplot Matrices