Last active
September 13, 2017 05:05
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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