Skip to content

Instantly share code, notes, and snippets.

@MartinBodocky
Last active August 29, 2015 14:03
Show Gist options
  • Save MartinBodocky/1b349bf4f55bb5bfa469 to your computer and use it in GitHub Desktop.
Save MartinBodocky/1b349bf4f55bb5bfa469 to your computer and use it in GitHub Desktop.
RProvider with Fslab nuget package!
(*
BEFORE you start to play you need to add
Fslab to your project by nuget package manager
*)
#nowarn "211" // Ignore warning that a search path does not exist on #I
#I "../packages/FSharp.Data.2.0.9/lib/net40/"
#r "FSharp.Data.dll"
#I "../../bin/"
#I "../packages/RProvider.1.0.13/lib/net40"
#r "RProvider.dll"
#r "RProvider.Runtime.dll"
#I "../packages/R.NET.Community.1.5.15/lib/net40"
#r "RDotNet.dll"
#r "RDotNet.NativeLibrary.dll"
#I "../packages/R.NET.Community.FSharp.0.1.8/lib/net40"
#r "RDotNet.FSharp.dll"
open RDotNet
open RProvider
open RProvider.``base``
open RProvider.graphics
open RProvider.stats
//install.package("tseries") in R/RStudio
open RProvider.tseries
open RProvider.zoo
open System
open System.Net
(* Getting data from Yahoo finance *)
open FSharp.Data
type Stocks = CsvProvider<"http://ichart.finance.yahoo.com/table.csv?s=SPX">
/// Returns prices of a given stock for a specified number
/// of days (starting from the most recent)
let getStockPrices stock count =
let url = "http://ichart.finance.yahoo.com/table.csv?s="
[| for r in Stocks.Load(url + stock).Take(count).Rows -> float r.Open |]
|> Array.rev
/// Get opening prices for MSFT for the last 255 days
let msftOpens = getStockPrices "MSFT" 255
// Retrieve stock price time series and compute returns
let msft = msftOpens |> R.log |> R.diff
// Build a list of tickers and get diff of logs of prices for each one
let tickers =
[ "MSFT"; "AAPL"; "X"; "VXX"; "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 scatter matrix.*)
(* Passing parameters between F# and R *)
let fun1 = R.eval(R.parse(text="function(i) {mean(rnorm(i))}"))
let nums = R.sapply(R.c(1,2,3),fun1)
(* Accessing results *)
let res = R.sum([|1;2;3;4|])
if res.Type = RDotNet.Internals.SymbolicExpressionType.IntegerVector then res.AsInteger().[0]
else failwithf "Expecting a Numeric but got a %A" res.Type
(* or you can use predefined active pattens*)
let getVectorResult (res : SymbolicExpression) =
match res with
| IntegerVector(iv) -> iv.[0]
| _ -> failwithf "Expecting a Numeric but got a %A" res.Type
getVectorResult res
(* Charts and plotting *)
(* Producing basic charts is as simple as this: *)
let widgets = [ 3; 8; 12; 15; 19; 18; 18; 20; ]
let sprockets = [ 5; 4; 6; 7; 12; 9; 5; 6; ]
R.plot(widgets)
R.plot(widgets, sprockets)
R.barplot(widgets)
R.hist(sprockets)
R.pie(widgets)
(* Saving plots to files on disk*)
// Required package to save charts
open RProvider.grDevices
// Create path to an image testimage.png on the Desktop
let desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
let path = desktop + @"\testimage.png"
// Open the device and create the file as a png.
// R.bmp, R.jpeg, R.pdf, ... will generate other formats.
R.png(filename=path, height=200, width=300, bg="white")
// Create the chart into the file
R.barplot(widgets)
// Close the device once the chart is complete
R.dev_off ()
(* Adding annotation to plot *)
R.barplot(widgets)
R.title(main="Widgets", xlab="Period", ylab="Quantity")
(* using list for namedparameters *)
R.plot(
namedParams [
"x", box widgets;
"type", box "o";
"col", box "blue";
"ylim", box [0; 25] ])
R.lines(
namedParams [
"x", box sprockets;
"type", box "o";
"pch", box 22;
"lty", box 2;
"col", box "red" ])
(*More elegant way to passing your parameters to R grapichs*)
namedParams [
"x", box widgets;
"type", box "o";
"col", box "blue";
"ylim", box [0; 25] ]
|> R.plot
namedParams [
"x", box sprockets;
"type", box "o";
"pch", box 22;
"lty", box 2;
"col", box "red" ]
|> R.lines
(* Generate some data for data frame*)
// Random number generator
let rng = Random()
let rand () = rng.NextDouble()
// Generate fake X1 and X2
let X1s = [ for i in 0 .. 9 -> 10. * rand () ]
let X2s = [ for i in 0 .. 9 -> 5. * rand () ]
// Build Ys, following the "true" model
let Ys = [ for i in 0 .. 9 -> 5. + 3. * X1s.[i] - 2. * X2s.[i] + rand () ]
(* Create data frame by passing named parameters *)
let dataset =
namedParams [
"Y", box Ys;
"X1", box X1s;
"X2", box X2s; ]
|> R.data_frame
(* We can do linear regression on it.*)
let result = R.lm(formula = "Y~X1+X2", data = dataset)
let getListValue (res : SymbolicExpression) (nameOfValue : string) =
match res with
| List(iv) -> iv.[nameOfValue].AsNumeric() |> Seq.toList
| _ -> failwithf "Expecting a List but got a %A" res.Type
// we can observe coefficients and residuals
let coefficients = result.AsList().["coefficients"].AsNumeric()
let residuals = result.AsList().["residuals"].AsNumeric()
//nicer way
let coefficients2 = getListValue result "coefficients"
let residuals2 = getListValue result "residuals"
(* We can call summary function from R*)
let summary = R.summary(result)
summary.AsList().["r.squared"].AsNumeric()
(* Plot our line from linear regression*)
R.plot result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment