DSPL 代表数据集发布语言。您可以将 DSPL 中描述的数据集导入 Google 公开数据浏览器,该工具可让您以可视化方式探索数据。
注意:如需使用公开数据上传工具将数据上传到 Google 公开数据,您必须拥有 Google 帐号。
本教程提供了有关如何准备基本 DSPL 数据集的分步示例。
DSPL 数据集是包含 XML 文件和一组 CSV 文件的软件包。CSV 文件是包含数据集的数据的简单表。XML 文件描述了数据集的元数据,包括测量结果等说明性元数据,以及表之间的引用等结构元数据。元数据让非专家用户可以探索和可视化您的数据。
理解本教程的唯一前提条件是充分了解 XML。对简单的数据库概念(例如表、主键)可能有所帮助,但并非强制性要求。参考资料:与本教程关联的完整 XML 文件和完整数据集软件包也可供查看。
概览
在开始创建数据集之前,我们先简要了解一下 DSPL 数据集包含的内容:
- 一般信息:关于数据集
- 概念:数据集中出现的“事物”的定义(例如国家/地区、失业率、性别等)
- Slice:包含数据的概念的组合
- 表:概念和切片的数据。概念表保存枚举,切片表保存统计数据
- 主题:用于通过添加标签,按有意义的层次结构整理数据集的概念
为了说明这些相当抽象的概念,请考虑本教程中使用的数据集(包含虚拟数据):人口和失业的统计时间序列,按国家/地区、美国各州和性别的不同组合进行汇总。
此示例数据集定义了以下概念:
- 国家/地区
- 性别
- 人口
- state
- 失业率
- 年
分类(例如状态)与概念表格相关联,而这些表格会列出枚举其所有可能的值(加利福尼亚州、亚利桑那州等)。概念中可能包含其他属性列,如州名或国家/地区。
“切片”定义了数据集中有统计信息的概念组合。切片包含维度和指标。在上图中,维度为蓝色,指标为橙色。在此示例中,切片 gender_country_slice
包含指标 population
和维度 country
、year
和 gender
的数据。另一个切片名为 country_slice
,用于提供各个国家/地区每年的人口总数(指标)。
除了维度和指标之外,切片还引用包含实际数据的表。
现在,我们将逐步了解如何在 DSPL 中创建此类数据集。
数据集信息
首先,我们需要为数据集创建一个 XML 文件。以下是示例数据集的 DSPL 说明的开头:
<?xml version="1.0" encoding="UTF-8"?> <dspl targetNamespace="http://www.stats-bureau.com/mystats" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.google.com/dspl/2010" xmlns:time="http://www.google.com/publicdata/dataset/google/time" xmlns:geo="http://www.google.com/publicdata/dataset/google/geo" xmlns:entity="http://www.google.com/publicdata/dataset/google/entity" xmlns:quantity="http://www.google.com/publicdata/dataset/google/quantity"> <import namespace="http://www.google.com/publicdata/dataset/google/time"/> <import namespace="http://www.google.com/publicdata/dataset/google/entity"/> <import namespace="http://www.google.com/publicdata/dataset/google/geo"/> <import namespace="http://www.google.com/publicdata/dataset/google/quantity"/> <info> <name> <value>My statistics</value> </name> <description> <value>Some very interesting statistics about countries</value> </description> <url> <value>http://www.stats-bureau.com/mystats/info.html</value> </url> </info> <provider> <name> <value>Bureau of Statistics</value> </name> <url> <value>http://www.stats-bureau.com</value> </url> </provider> ... </dspl>
数据集说明以顶级 <dspl>
元素开头。targetNamespace
特性包含唯一标识此数据集的 URI。数据集的命名空间在发布数据集时尤为重要,因为它将是数据集的全局标识符以及他人引用该数据集的方式。
请注意,可以省略 targetNamespace
属性。在这种情况下,导入数据集时会自动生成唯一命名空间。
使用其他数据集中的信息
通过重用其他数据集的定义和数据,您可以重复使用这些数据集。每个 <import>
元素都会指定此数据集将引用的另一个数据集的命名空间。
在示例数据集中,我们需要来自 http://www.google.com/publicdata/dataset/google/quantity(Google 创建的数据集,其中包含用于定义数字数量的概念)和时间、实体和地理位置数据集的一些定义,它们分别提供与时间、实体和地理位置相关的定义。
顶部的 <dspl>
元素提供命名空间前缀声明(例如,xmlns:time="http://..."
)。需要前缀声明才能以简洁方式引用其他数据集中的元素。例如,time:year
会引用已导入数据集中 year
的定义,该命名空间与前缀 time
相关联。
数据集和提供商信息
<info>
元素包含有关数据集的一般信息:名称、说明以及可找到更多信息的网址。
<provider>
元素包含有关数据集提供商的信息:其名称以及提供更多信息的网址(通常是数据提供商的首页)。
定义概念
现在我们已提供有关数据集的一些常规信息,接下来可以开始定义数据集的内容了。我们的下一个目标是添加过去 50 年中国家/地区的人口统计信息。
我们首先需要提供一些关于人口、国家/地区和年份的概念的定义。在 DSPL 中,这些定义称为概念。
“概念”是对数据集中出现的一种数据类型的定义。与给定概念对应的数据值称为该概念的实例。
人口
我们先来定义人口概念。在 DSPL 文档中,概念是在数据集和提供程序信息之后的 <concepts>
元素中定义的。
这是一个总体概念,只包含任何概念所需的最少信息:id
(唯一标识符)、name
和 type
。
<dspl ...> ... <concepts> <concept id="population"> <info> <name> <value>Population</value> </name> </info> <type ref="integer"/> </concept> ... </concepts>
下面对此示例进行了详细说明:
- 每个概念都必须提供一个
id
,用于唯一标识数据集内的概念。这意味着,同一数据集中定义的两个概念不能具有相同的 ID。 - 就像数据集及其提供程序一样,
<info>
元素会提供有关概念的文本信息,例如名称和说明。 <type>
元素指定该概念实例的数据类型(即其“值”)。 在此示例中,population
的类型为integer
。DSPL 支持以下数据类型:string
integer
float
boolean
date
国家/地区
现在,我们来编写国家/地区概念的定义:
<concept id="country"> <info> <name><value>Country</value></name> <description> <value>My list of countries.</value> </description> </info> <type ref="string"/> <property id="name"> <info> <name><value>Name</value></name> <description> <value>The official name of the country</value> </description> </info> <type ref="string" /> </property> <table ref="countries_table" /> </concept>
国家/地区概念定义以前面的概念开头,包含 id
、info
和 type
。
概念值
像国家/地区这样的分类概念会枚举所有可能的实例。也就是说,您可以列出所有可以引用的国家/地区。但为此,每个国家/地区都需要一个唯一标识符。
此示例使用 ISO 国家/地区代码来标识国家/地区;这些代码是 string
类型。
在此示例中,您无需使用 ISO 代码,也可以使用国家/地区名称。但是,名称因语言而异,可能会随时间而变化,并且并非总是在所有数据集中使用。对于国家/地区以及类别的一般概念,最好选择简短、稳定、常用且独立于语言的标识符(如果存在)。
概念属性
除了 id
,国家/地区概念还有一个 <property>
元素,用于指定国家/地区的名称。
也就是说,国家/地区名称(“爱尔兰”)是爱尔兰 id
的属性。属性是指 DSPL 提供有关概念实例的额外结构化信息的方式。
与概念本身一样,属性具有 id
、info
和 type
。
概念数据
最后,国家/地区概念具有 <table>
元素。此元素引用一个列有所有国家/地区的列表。
对一些概念来说,使用表格是有意义的,但对另一些概念则不然。例如,枚举概念填充的所有可能值没有意义。但是,如果您引用某个概念的表,则该表必须包含该概念的所有实例,例如,它必须列出每个国家/地区,而不仅仅是示例示例。
数据集定义 countries_table
表的方式如下:
... <tables> <table id="countries_table"> <column id="country" type="string"/> <column id="name" type="string"/> <data> <file format="csv" encoding="utf-8">countries.csv</file> </data> </table> ... </tables>
国家/地区表会指定表格的列及其类型,并引用包含数据的 CSV 文件。此 CSV 文件可以捆绑到数据集 XML 中,也可通过 HTTP、HTTPS 或 FTP 远程访问。在后一种情况下,您需要将 countries.csv
替换为网址,例如 http://www.myserver.com/mydata/countries.csv
。
无论在何处存储,CSV 文件均如下所示:
country, name AD, Andorra AF, Afghanistan AI, Anguilla AL, Albania US, United States
表格的第一行列出了 DSPL table
定义中指定的列 ID。以下每一行对应一个国家/地区概念实例。如果概念具有表,则该表必须包含概念的所有实例,在本例中,必须列出所有国家/地区。
列会根据国家/地区 ID 映射到其国家/地区概念及其属性。第一列的 ID country
与概念 ID 匹配。这意味着,此列包含由国家/地区概念定义的唯一国家/地区标识符。下一列对应于国家/地区概念的 name
属性。此列中的值与 name
属性的值匹配。
概念表的 CSV 数据有几项要求:
- 数据文件第一行中的列标题必须与数据所对应概念的
id
属性和id
属性完全一致(但顺序可能会有所不同)。 - 每行中元素数量必须与概念上属性数量完全相同(即使该值为空)。
- 概念的
id
字段(此处为国家/地区代码)的每个值都必须是唯一的,且不得为空(空字段是指不含或仅包含空白字符的字段)。 - 引用其他概念的属性值必须为空或是所引用概念的有效值。
- 包含英文逗号、英文双引号或换行符的字符的值必须完全用英文双引号括起来。
- 值内的任何字面量双引号都必须紧接另一个英文双引号。
年份
我们需要的国家/地区人口数据的最后一个概念是代表年份的概念。我们将使用导入的数据集中“年份”概念“http://www.google.com/publicdata/dataset/google/time”,而不是定义一个新概念。为此,我们需要将其引用为 time:year
,其中 time
表示引用的数据集,year
表示概念。
规范概念
time:year
是 Google 定义的一小部分规范概念的一部分。规范概念会提供有关时间、地理位置、数字数量、单位等的基本定义。
实际上,上面定义的“国家/地区”概念属于规范概念。我们在此处创建该代码只是为了便于说明。
您应该尽可能在数据集中使用规范概念,无论是直接使用,还是通过扩展使用(有关更多信息,请参见下文)。规范概念可让您的数据与其他数据集相当,并为公开数据浏览器中的数据集启用功能。例如,若要为一段时间内的数据添加动画效果,或在地图上显示地理数据,则需分别使用 time
和 geo
规范概念。
第一个 Slice
现在我们已经有了关于人口、国家/地区和年份的概念,接下来我们要汇总这些知识!
为此,我们需要创建一个结合了这些切片的切片。在 DSPL 中,切片是存在数据的概念的组合。
为什么不直接创建包含正确列的表呢?因为切片会根据数据集概念捕获数据集的信息。随着我们创建更多数据集,这一点将变得更加清晰。
Slice 显示在 DSPL 文件中的 <slices>
元素下,该元素必须紧跟在 concepts
部分之后。
<slices> <slice id="countries_slice"> <dimension concept="country"/> <dimension concept="time:year"/> <metric concept="population"/> <table ref="countries_slice_table"/> </slice> </slices>
就像概念一样,每个切片都有一个 id
(countries_slice
),用于唯一标识数据集内的切片。
Slice 包含两种概念引用:维度和指标。指标值因维度值而异。在此示例中,population
(指标)的值因维度 country
和 year
而异。
与概念一样,切片包含对包含切片数据的表的引用。引用的表的切片的每个维度和指标都必须有一列。与概念一样,切片的维度和指标会映射到具有相同 ID 的表列。
Slice 表
人口切片的表格会显示在 DSPL 文件的 tables
部分中:
<tables> ... <table id="countries_slice_table"> <column id="country" type="string"/> <column id="year" type="date" format="yyyy"/> <column id="population" type="integer"/> <data> <file format="csv" encoding="utf-8">country_slice.csv</file> </data> </table> ... </tables>
请注意,year
列附带的 format
属性指定了年份的格式。受支持的日期格式是由 Joda 日期时间格式定义。
countries_slice
表会指定表中的列及其类型,并指向包含数据的 CSV 文件。CSV 文件如下所示:
country, year, population AF, 1960, 9616353 AF, 1961, 9799379 AF, 1962, 9989846 AF, 1963, 10188299 ...
数据表中的每一行都包含维度 country
和 year
的唯一组合,以及 population
指标的对应值(例如,1960 年阿富汗人口 - 指标 - 维度)。
请注意,country
列中的值与 country
概念的值/标识符(即国家/地区的 ISO 3166 双字母代码)一致。
切片的 CSV 数据必须满足以下限制条件:
- 维度字段的每个值(如
country
和year
)都不得为空。指标字段的值(例如population
)可以为空。空值不以字符表示。 - 引用某个概念的维度字段的每个值都必须存在于该概念的数据中。例如,值
AF
必须存在于country
概念数据表中。 - 每个维度值的唯一组合(例如
AF, 2000
)只能出现一次。 - 数据应按非时间维度列(按任意顺序)排序,然后可视需要按任何其他列排序。例如,在包含
[date, dimension1, dimension2, metric1, metric2]
列的表中,您可以依次按dimension1
、dimension2
、date
排序,但无法按date
和维度排序。
总结
现在,DSPL 中有足够的数据,可以描述国家/地区人口数据。总结一下,我们要做的是:
- 创建数据集及其提供商的 DSPL 标头和说明
- 针对人口创建一个概念,再针对国家/地区创建一个概念,通过 csv 文件枚举所有国家/地区及其名称。
- 使用从不同国家/地区的人口数量创建一段时间的切片,并引用 Google 导入的时间数据集中已经定义的年份概念。
在本教程的其余部分,我们将通过在更多切片中添加更多维度以及按主题分组更多指标来丰富数据集。
添加维度:美国各州
现在,我们通过添加美国各州的人口数据来丰富我们的数据集。我们首先需要定义状态的概念。这与我们之前定义的“国家/地区”概念非常相似。
<concept id="state" extends="geo:location"> <info> <name> <value>state</value> </name> <description> <value>US states, identified by their two-letter code.</value> </description> </info> <property concept="country" isParent="true" /> <table ref="states_table"/> </concept>
概念扩展和属性参考文档
状态概念引入了 DSPL 的几项新功能。
首先,状态扩展了另一个概念,即 geo:location
(在数据集开始时导入的外部地理位置数据集中定义)。从语义上讲,这意味着 state
是一种 geo:location
。这导致它继承了 geo:location
的所有属性。特别是,位置信息定义了 latitude
和 longitude
的属性;通过扩展前一个概念,这些属性也会应用到状态。此外,由于位置信息继承自 entity:entity
,因此状态也会获取后者的所有属性,包括 name
、description
和 info_url
。
注意:从技术上讲,之前定义的国家/地区概念应该也从 geo:location
扩展而来。为简单起见,我们之前省略了这一点;但是,我们在最终 XML 文件中加入了国家/地区继承位置。
注意:您可以在自己的数据集中使用 extends
构造,以重复使用其他数据集定义的信息。如需使用 extends
,您的概念的所有实例都必须是您要扩展的概念的有效实例。通过扩展程序,您可以添加其他属性和特性,并将一组实例限制为扩展概念的子集实例。
除了继承之外,状态属性还引入了概念引用。具体而言,状态概念具有一个名为 country
的属性,该属性引用了我们上面创建的国家/地区概念。这通过使用 concept
属性来完成。请注意,此属性不提供 ID,而只是提供概念引用。这相当于创建一个与所引用概念的 ID 值相同的 ID(即,在此示例中为 country
)。州和郡之间的层次结构关系是通过对引用设置 isParent="true"
属性捕获的。一般而言,具有层次结构关系的维度(例如地理位置)应以这种方式表示,其中子概念的属性使用 isParent
属性引用父概念。
状态的表定义如下所示:
<tables> ... <table id="states_table"> <column id="state" type="string"/> <column id="name" type="string"/> <column id="country" type="string"> <value>US</value> </column> <column id="latitude" type="float"/> <column id="longitude" type="float"/> <data> <file format="csv" encoding="utf-8">states.csv</file> </data> </table> ... </tables>
“国家/地区”列为所有州/省设置了一个常量值。在 DSPL 中指定该参数可以避免对数据中的每个状态重复该值。另请注意,由于状态是从 geo:location
继承的,因此 name
、latitude
和 longitude
列也包含在内。另一方面,某些继承的属性(例如,description
)没有列;没关系,如果概念定义表中省略了某个属性,则系统会假定其值对于该概念的每个实例都未定义。
CSV 文件如下所示:
state, name, latitude, longitude AL, Alabama, 32.318231, -86.902298 AK, Alaska, 63.588753, -154.493062 AR, Arkansas, 35.20105, -91.831833 AZ, Arizona, 34.048928, -111.093731 CA, California, 36.778261, -119.417932 CO, Colorado, 39.550051, -105.782067 CT, Connecticut, 41.603221, -73.087749 ...
由于我们已经有了关于人口和年份的概念,因此可以重复使用它们为州人口定义新的切片。
<slices> <slice id="states_slice"> <dimension concept="state"/> <dimension concept="time:year"/> <metric concept="population"/> <table ref="states_slice_table"/> </slice> </slices>
数据表定义如下所示:
<tables> ... <table id="states_slice_table"> <column id="state" type="string"/> <column id="year" type="date" format="yyyy"/> <column id="population" type="integer"/> <file format="csv" encoding="utf-8">state_slice.csv</file> </table> ... </tables>
CSV 文件如下所示:
state, year, population AL, 1960, 9616353 AL, 1961, 9799379 AL, 1962, 9989846 AL, 1963, 10188299
等等,我们为什么要创建新切片,而不是向前一个切片添加其他维度?
包含国家/地区和国家/地区维度的切片是不正确的,因为某些行针对国家/地区数据,某些行针对州数据。某些维度的表中会有“空洞”,这是不允许的(请注意,缺失值只能用于指标,而不允许维度)。
尺寸充当切片的“主键”。也就是说,每个数据行的所有维度都必须有相应的值,并且每个数据行的所有维度的值都不得完全相同。
添加指标:失业率
现在,让我们为数据集再添加一个指标:
<concept id="unemployment_rate" extends="quantity:rate"> <info> <name> <value>Unemployment rate</value> </name> <description> <value>The percent of the labor force that is unemployed.</value> </description> <url> <value>http://www.bls.gov/cps/cps_htgm.htm</value> </url> </info> <type ref="float/> <attribute id="is_percentage"> <type ref="boolean"/> <value>true</value> </attribute> </concept>
此指标的 info
部分包含名称、说明和网址(链接到美国劳工统计局)。
此概念还扩展了 quantity:rate
规范概念。
数量数据集定义了表示数字数量的核心概念。在数据集中,您应通过扩展相应的数量概念来创建数值概念。因此,从技术上讲,应该从 quantity:amount
扩展上面定义的 population
概念。
概念属性
此概念还引入了属性的构造。在此示例中,属性用于表明 unemployment_rate
是百分比。is_percentage
属性继承自此概念扩展的 quantity:rate
概念。Public Data Explorer 会使用此信息在直观呈现数据时显示百分比符号。
特性提供了一种将概念/值对附加到概念的常规机制(与将其他值与概念的实例相关联的属性形成对比)。与概念和属性一样,属性具有 id
、info
和 type
。与属性一样,它们也可以引用其他概念。
属性不仅仅适用于预定义的通用内容,例如数字属性。您可以为概念定义自己的属性。
添加美国各州的失业率数据
现在,我们准备好添加美国各州的失业率数据。由于失业率是一项指标,而且我们已经拥有州的人口数据,因此我们可以将其添加到州和年维度的切片中:
<slices> ... <slice id="states_slice"> <dimension concept="state"/> <dimension concept="time:year"/> <metric concept="population"/> <metric concept="unemployment_rate"/> <table ref="states_slice_table"/> </slice> ... </slices>
... 并在表定义中添加另一列:
<tables> ... <table id="states_slice_table"> <column id="state" type="string"/> <column id="year" type="date" format="yyyy"/> <column id="population" type="integer"/> <column id="unemployment_rate" type="float"/> <data> <file format="csv" encoding="utf-8">state_slice.csv</file> </data> </table> ... </tables>
... 以及 CSV 文件:
state, year, population, unemployment_rate AL, 1960, 9616353, 5.1 AL, 1961, 9799379, 5.2 AL, 1962, 9989846, 4.8 AL, 1963, 10188299, 6.9
我们之前说过,对于每个切片,维度会构成该切片的主键。此外,对于给定的维度组合,每个数据集只能包含一个切片。这些维度可用的所有指标必须属于同一切片。
更多维度:按性别细分人口
让我们使用不同国家/地区按性别细分的人口数据来丰富我们的数据集。现在,您已经开始知道......我们首先需要添加一个性别概念:
<concept id="gender" extends="entity:entity"> <info> <name> <value>Gender</value> </name> <description> <value>Gender, Male or Female</value> </description> <pluralName> <value>Genders</value> </pluralName> <totalName> <value>Both genders</value> </totalName> </info> <type ref="string"/> <table ref="genders_table"/> </concept>
性别概念 info
部分有一个 pluralName
,它提供用于指代性别概念多个实例的文本。info
部分还包含一个 totalName
,它提供的文本用于引用整个性别概念的所有实例。Public Data Explorer 使用这两者来显示与性别概念相关的信息。通常,您应该为可用作维度的概念提供它们。
请注意,性别概念也扩展自 entity:entity
。这对于用作维度的概念来说是一种很好的做法,因为您可以通过该属性为各种概念实例添加自定义名称、网址和颜色。
性别概念会引用 genders_table
表,其中包含性别的可能值及其显示名称(此处省略)。
如需向数据集添加按性别划分的人口,我们需要创建一个新的切片(请注意:每个可用的维度组合都对应于数据集中的一个切片)。
<slice id="countries_gender_slice"> <dimension concept="country"/> <dimension concept="gender"/> <dimension concept="time:year"/> <metric concept="population"/> <table ref="countries_gender_slice_table"/> </slice>
Slice 的表定义如下所示:
<table id="countries_gender_slice_table"> <column id="country" type="string"/> <column id="gender" type="string"/> <column id="year" type="date" format="yyyy"/> <column id="population" type="integer"/> <data> <file format="csv" encoding="utf-8">gender_country_slice.csv</file> </data> </table>
该表的 CSV 文件如下所示:
country, gender, year, population AF, M, 1960, 4808176 AF, F, 1960, 4808177 AF, M, 1961, 4899689 AF, F, 1961, 4899690...
与以前的国家/地区、人口和失业率细分相比,此维度有一个额外的维度;人口指标的每个值不仅对应于特定的国家/地区和年份,而且还对应于特定的性别。
请注意,我们创建了一个“稀疏”数据集。并非所有指标都适用于所有维度:人口数量按国家/地区统计,并且每年都会计入美国各州,而失业率仅适用于国家/地区。按性别细分仅适用于按国家/地区划分的人口;无法用于失业率指标,而不适用于州维度。稀疏度也可以在数据级别存在,其中某些指标的某些维度值没有值,但 DSPL 中没有该值。
主题
我们将使用我们的数据集的最后一个 DSPL 功能是主题。主题用于按层次结构对概念进行分类,应用使用主题来帮助用户转到您的数据。
在 DSPL 文件中,主题会显示在概念前面。以下是主题层次结构的示例:
<dspl ... > ... <topics> <topic id="geography"> <info> <name> <value>Geography</value> </name> </info> </topic> <topic id="social_indicators"> <info> <name> <value>Social indicators</value> </name> </info> </topic> <topic id="population_indicators"> <info> <name> <value>Population indicators</value> </name> </info> </topic> <topic id="poverty_and_income"> <info> <name> <value>Poverty & income</value> </name> </info> </topic> <topic id="health"> <info> <name> <value>Health</value> </name> </info> </topic> </topics>
您可以根据需要嵌套深层的主题。
如需使用主题,您只需从概念定义中引用这些主题,如下所示:
<concept id="population"> <info> <name> <value>Population</value> </name> <description> <value>Size of the resident population.</value> </description> </info> <topic ref="population_indicators"/> <type ref="integer"/> </concept>
一个概念可能会引用多个主题。
提交数据集
现在,您已创建数据集,下一步是将其压缩,并将 ZIP 文件上传到 Google 公开数据浏览器工具中。如果您遇到任何问题,请参阅常见问题解答,其中讨论了最常见的上传问题。
参考信息,您还可以下载与本教程关联的完整 XML 文件和完整的数据集软件包。
相关资料
恭喜您创建了自己的第一个 DSPL 数据集!现在您已了解基础知识,我们建议您仔细阅读开发者指南,其中记录了多语言支持和可映射概念等“高级”DSPL 功能。
您可能还需要查看更多示例数据集。