13.4.3 收集有关地区的统计信息
我们的目标是展示自 1990 年以来,不同地区森林面积的变化。我们需要遍历所有已有的地区,检查数据是否可用,找到下载的指标值。这可以通过使用我们创建的映射,非常轻松地完成,因为已经用年份和地区 ID 作为关键字。
需要小心的是有一些数据可能会缺失,因此,我们要过滤掉所有没有我们需要年份数据的地区。另外,我们还想要显示森林总面积,而不是百分比,因此,在返回数据之前,要进行简单的计算。虽然听起来可能很难,但是,代码并不非常复杂。在清单 13.17 中,我们只要在交互式 F# 中输入几条命令,能得到想要收集的数据。
清单 13.17 计算森林面积(交互式 F#)
> let calculateForests(area:float<km^2>, forest:float<percent>) = <--[1] 计算森林总面积
let forestArea = forest * area
forestArea / 100.0<percent>
;;
val calculateForests : float<km ^ 2> * float<percent> -> float<km ^ 2>
> let years = [ 1990; 2000; 2005 ]
let dataAvailable(key) = <-- [2] 对于给定的给定的键,值是否可用?
years |> Seq.forall (fun y –>
(Map.contains (y, key) areas) &&
(Map.contains (y, key) forests));;
val years : int list
val dataAvailable : string –> bool
> let getForestData(key) = <-- [3] 得到每年的值
[| for y in years do
yield calculateForests(areas.[y, key], forests.[y, key]) |];;
val getForestData : string -> float<km ^ 2> array
> let stats = seq { <-- [4] 对所有地区,查找可用数据
for name in regions do
if dataAvailable(name) then
yield name, getForestData(name) };;
val stats : seq<string * float<km ^ 2> array>
清单 13.17 定义了几个辅助函数,处理下载的数据,并定义名为 stats(统计数据)的值保存最后的结果。由于有了计量单位,可以很容易看出第一个函数的用途[1],它用该地区的总面积和森林面积占比,计算森林总面积,以平方公里计。
第二个函数[2]检查指定的地区是否有三年我们所需要的数据,它使用的函数 Map.contains 测试 F# 映射(第二个参数)是否包含第一个参数的关键字。最后一个辅助函数[3]看起来和第二个很相似,假定数据可用,以年和地区作为关键字,对所有监控的年份,从映射中提取数据;然后,使用第一个函数,计算出原始数据的森林面积。
组合最后两个函数,就可以收集所有地区的统计数字了[4],返回元组的序列,元组的第一个元素为地区名,第二个元素为数组,数组有三个元素,对应于所监控的三年的值。
在交互式 F# 中获取数据以后,虽然可以在互动窗口中进行观察,但是,很难通过输出数据找出模型。为了能够从收集的数据中获取更多的信息,必须以更友好的方式对数据进行可视化,例如,使用 Microsoft Excel。