Skip to content

Instantly share code, notes, and snippets.

@sir-deenicus
Last active September 13, 2017 05:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sir-deenicus/5447061 to your computer and use it in GitHub Desktop.
Save sir-deenicus/5447061 to your computer and use it in GitHub Desktop.
A hastily constructed script to rank countries according to some criteria and generate an html table.
open FSharp.Data
let data = WorldBankData.GetDataContext()
let scoreArr = [|
"Household final consumption expenditure per capita (constant 2000 US$)", (-7.5, 50000.);
"Intentional homicides (per 100,000 people)", (-20., 1000.);
"Fixed broadband Internet subscribers (per 100 people)", (9.5, 100.);
"Burden of customs procedure, WEF (1=extremely inefficient to 7=extremely efficient)", (6., 7.);
"CPIA transparency, accountability, and corruption in the public sector rating (1=low to 6=high)", (6., 6.);
"GINI index", (-5., 100.);
"Ease of doing business index (1=most business-friendly regulations)", (-9.5, 185.);
"International migrant stock (% of population)", (4.5, 5.); //1st derivative used
"Health expenditure, public (% of total health expenditure)", (5., 100.);
"Net migration", (6., 500000.); //1st deriv used
"Researchers in R&D (per million people)", (5., 10000.);
"Poverty headcount ratio at national poverty line (% of population)", (-4.,100.);
"Improved sanitation facilities, urban (% of urban population with access)", (7.5,100.);
"Improved water source, urban (% of urban population with access)", (7., 100.);
"Internet users (per 100 people)", (10.5, 100.);
"Research and development expenditure (% of GDP)" , (5.,100.);
"Literacy rate, adult female (% of females ages 15 and above)" , (5.5,100.);
"Access to electricity (% of population)", (8.5, 100.);
"Labor force, female (% of total labor force)" , (20., 100.) |]
let scoreMap = scoreArr |> Array.map (fun (featname, (w,maxv)) -> //forgot some values can be < 0
match featname with
| "Net migration" -> (featname,(w,-500000.,maxv))
|"International migrant stock (% of population)" -> (featname,(w,-5.,maxv))
| _ -> (featname, (w,0.,maxv))) |> Map.ofArray
let scaleTo rmin rmax rangemin rangemax value =
let adjrmin, adjrmax, adjval = if rangemin < 0. then 0., -rangemin + rangemax , -rangemin + value
else rangemin, rangemax , value //translate to 0
(adjval - adjrmin)/(adjrmax - adjrmin) * (rmax-rmin) + rmin
let scale0to10 = scaleTo 0. 10.
let getRelevantData (c: WorldBankData.ServiceTypes.Country) =
[| c.Indicators.``Household final consumption expenditure per capita (constant 2000 US$)``; //0
c.Indicators.``Intentional homicides (per 100,000 people)``;
c.Indicators.``Access to electricity (% of population)``;
c.Indicators.``Fixed broadband Internet subscribers (per 100 people)``;
c.Indicators.``Internet users (per 100 people)``;
c.Indicators.``Ease of doing business index (1=most business-friendly regulations)``; //5
c.Indicators.``Burden of customs procedure, WEF (1=extremely inefficient to 7=extremely efficient)`` ;
c.Indicators.``CPIA transparency, accountability, and corruption in the public sector rating (1=low to 6=high)``;
c.Indicators.``GINI index``;
c.Indicators.``Labor force, female (% of total labor force)``;
c.Indicators.``Literacy rate, adult female (% of females ages 15 and above)``; //10
c.Indicators.``Health expenditure, public (% of total health expenditure)``;
c.Indicators.``International migrant stock (% of population)``;
c.Indicators.``Net migration``;
c.Indicators.``Researchers in R&D (per million people)``;
c.Indicators.``Research and development expenditure (% of GDP)``; //15
c.Indicators.``Improved sanitation facilities, urban (% of urban population with access)``;
c.Indicators.``Improved water source, urban (% of urban population with access)``;
c.Indicators.``Poverty headcount ratio at national poverty line (% of population)``;
|]
//This was used to generate the array key map above. Easy peasy.
data.Countries.``United States``|> getRelevantData |> Array.map (fun ri -> ri.Name)
//Important things are technology,internet, corruption, healthcare, cost of living and migration query{
let getData (countries : WorldBankData.ServiceTypes.Countries) =
query{
for country in countries do
let cdat = getRelevantData country |> Array.map (fun ri -> if ri.Values |> Seq.length < 1 then None else Some ri)
let inf = cdat |> Array.map (fun ori ->
maybe{
let! ri = ori
let weight, minval, maxval = scoreMap.[ri.Name]
let x = if ri.Name.Contains("migra") then
let yrs, ds = [|for (year, point) in ri do
if year > 1990 then yield float year,point|]
|> Array.unzip
let slope,_,_,_,_ = Prelude.Math.simpleStats yrs ds
slope
else (ri.Values |> Seq.last)
return (ri.Name, x, weight * (scale0to10 minval maxval x))})
let score = inf |> Array.filter (Option.isSome) |> Array.sumBy (Option.get >> third)
sortByDescending score
select (country,score, inf)
} |> Seq.toArray
let p = getData data.Regions.Africa.Countries
let p2 = getData data.Regions.``East Asia & Pacific (all income levels)``.Countries
let p3 = getData data.Regions.``Latin America & Caribbean (all income levels)``.Countries
let p4 = getData data.Regions.``Middle East & North Africa (all income levels)``.Countries
let p5 = getData data.Regions.``Europe & Central Asia (all income levels)``.Countries
let p6 = getData data.Regions.``North America``.Countries
let alls = [p;p2 ; p3; p4;p5;p6] |> Seq.concat
let malls = alls |> Seq.toArray
|> Array.map (fun x -> (fst3 x).Name ,x)
|> Map.ofArray // remove duplicates
|> Map.toArray
|> Array.unzip
|> snd
let cn = ref 0
let flist = query { for ((a,b,c)) in malls do
sortByDescending b
select((incr cn;!cn),a,b,c)} |> Seq.toArray
query { for (i,a,b,c) in flist do
sortByDescending b
select(i,a,b)} |> Seq.toArray
let html =
String.Join("<tr>",
flist |> Array.map (fun (rank,cnm, score,datum) ->
sprintf "<td>%d</td><td>%s</td>%s</tr>\n" rank cnm.Name
(String.Join("",datum |> Array.map (function | None -> "<td></td>"
| Some(_,v,_) -> "<td>" + string (round v 1) + "</td>")))) )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment