Developed with Davide Costa
#r "nuget: FSharp.Data, 5.0.2"
#r "nuget: FSharp.Stats, 0.5.0"
#r "nuget: Plotly.NET, 3.*"
#r "nuget: Plotly.NET.Interactive, 3.*"
open FSharp.Data
open FSharp.Stats
open FSharp.Stats.Correlation
open Plotly.NET
let [<Literal>] CsvPath = __SOURCE_DIRECTORY__ + "/FootballPlayers.csv"
type FootballPlayersCsv = CsvProvider<CsvPath>
let playerStatsTable =
FootballPlayersCsv.GetSample().Rows
|> Seq.toList
1 From playerStatsTable create a bar chart with the sum of GoalsScored (y-axis) by Age(x-axis)
3 From playerStatsTable create a bars chart with the average GoalsScored (y-axis) by Age(x-axis)
Now that you know how to work with the dataset using the most common List functions, we still need to practice how to create usefull plots with the data.
For plotting in F# we load Plotly.NET
nuget and open the Plotly.NET
namespace.
Documentation links:
It will be helpfull to check the documentation before starting the exercises.
let sumGoalsScoredByLeague =
playerStatsTable
|> List.groupBy(fun x -> x.League)
|> List.map(fun (league, playerStats) ->
(league,
playerStats |> List.sumBy(fun x -> x.GoalsScored)))
let sumGoalsScoredByLeagueChart =
sumGoalsScoredByLeague
|> Chart.Column
|> Chart.withYAxisStyle("Sum of Goals Scored")
|> Chart.withXAxisStyle("Top 5 Football Leagues")
|> Chart.withTitle("Sum of Goals Scored by League")
sumGoalsScoredByLeagueChart
Hints:
Group playerStatsTable
by Age
using List.groupBy
.
Map the returned List of tuples, into an List of tuples with two elements.
First element: age. The first element of the List.groupBy
output. Which corresponds to the Age groups.
Second element: sum of goals scored by Age
, use List.sumBy
applied to the second element of the List.groupBy
output. Which corresponds to all the rows per Age
group.
Then, store this new List of tuples to a variable. (In this case call it sumGoalsScoredByAge
).
After that in order to create a bar chart we need to follow the syntax: Chart.Column
.
Use the syntax Chart.withYAxisStyle("Sum of Goals Score")
to label the y-axis.
Use the syntax Chart.withXAxisStyle("Age")
to label the x-axis.
Use the syntax Chart.withTitle("Sum of Goals Score by Age")
to give a title to the chart.
Then Pipe (|>
) to Chart.Show
if you want to observe the chart.
answer
// write your code here, see website for solution.
let averageGoalsScoredByLeague =
playerStatsTable
|> List.groupBy(fun x -> x.League)
|> List.map(fun (league, playerStats) ->
(league,
playerStats |> List.averageBy(fun x -> float x.GoalsScored)))
let averageGoalsScoredByLeagueChart =
averageGoalsScoredByLeague
|> Chart.Column
|> Chart.withYAxisStyle("Average of Goals Scored")
|> Chart.withXAxisStyle("Top 5 Football Leagues")
|> Chart.withTitle("Average of Goals Scored by League")
averageGoalsScoredByLeagueChart
Hints:
Filter playerStatsTable
by Position
to get only forward position (Position = "FW"
), use List.Filter
.
Group playerStatsTable
by Age
using List.groupBy
.
Map the returned List of tuples, into an List of tuples with two elements.
First element: age --> The first element of the List.groupBy
output. Which corresponds to the Age groups.
Second element: sum of total GoalsScored divided by the total games played by age.
Note that you can get the total games played by using List.sumBy(fun x -> x.MatchesPlayed)
.
Also remember to transform the variables to floats
before dividing to get the exact results.
Then, store this new List of tuples to a variable. (Name it averageGoalsPerMatchByAgeFW
).
After that, in order to create a bars chart we need to follow the syntax: Chart.Column
, you just need to pipe (|>
) the variable averageGoalsPerMatchByAgeFW
to Chart.Column
.
Use the syntax Chart.withYAxisStyle("Average of Goals Scored Per Match")
to label the y-axis.
Use the syntax Chart.withXAxisStyle("Age")
to label the x-axis.
Use the syntax Chart.withTitle("Average of Goals Scored Per Match by Age")
to give a title to the chart.
Then Pipe (|>
) to Chart.Show
if you want to observe the chart.
answer
// write your code here, see website for solution.