批量抓取保存处理国家数据库数据的一点小心得

国家数据库提供了海量的电子统计数据,免去了逐年查询录入整理数据的的麻烦,同时我们还能找到提供国家数据库接口的R包,是我们能够直接在R中查询处理数据,很是方便。最近在使用过程中发现了分地域年度指标获取过程中存在一些小问题,于是结合最近所学写了两个函数,实现了批量读取保存处理国家数据库数据,记下过程以留后用。

准备工具

首先需要介绍的是rstatscn包,这个包提供了国家数据库的R接口,具体的函数介绍这里不在重复,请参照作者文档。rstatscn提供很方便的数据查询函数,大大简化了数据获得的方法。我们可以通过下面命令安装rstatscn包。

1
install.packages("rstatscn")

问题

但是在进行分省年度数据查询时,是下面这样的结果。有时一个产业分类下一个地区会有多个指标的数据,而这样只是显示出一个。为了获取全部的数据,我们只能把数据抓取下来自己处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
> library(rstatscn)
> statscnQueryData("A010101",dbcode='fsnd',rowcode='reg')
201420132012201120102009200820072006
北京市 0 0 0 0 0 0 0 0 0
天津市 0 0 0 0 0 0 0 0 0
河北省 11 11 11 11 11 11 11 11 11
山西省 11 11 11 11 11 11 11 11 11
内蒙古自治区 12 12 12 12 12 12 12 12 12
辽宁省 14 14 14 14 14 14 14 14 14
吉林省 9 9 9 9 9 9 9 9 9
黑龙江省 13 13 13 13 13 13 13 13 13
上海市 0 0 0 0 0 0 0 0 0
江苏省 13 13 13 13 13 13 13 13 13
浙江省 11 11 11 11 11 11 11 11 11
安徽省 16 16 16 16 17 17 17 17 17
福建省 9 9 9 9 9 9 9 9 9
江西省 11 11 11 11 11 11 11 11 11
山东省 17 17 17 17 17 17 17 17 17
河南省 17 17 17 17 17 17 17 17 17
湖北省 13 13 13 13 13 13 13 13 13
湖南省 14 14 14 14 14 14 14 14 14
广东省 21 21 21 21 21 21 21 21 21
广西壮族自治区 14 14 14 14 14 14 14 14 14
海南省 3 3 3 2 2 2 2 2 2
重庆市 0 0 0 0 0 0 0 0 0
四川省 21 21 21 21 21 21 21 21 21
贵州省 9 9 9 9 9 9 9 9 9
云南省 16 16 16 16 16 16 16 16 16
西藏自治区 7 7 7 7 7 7 7 7 7
陕西省 10 10 10 10 10 10 10 10 10
甘肃省 14 14 14 14 14 14 14 14 14
青海省 8 8 8 8 8 8 8 8 8
宁夏回族自治区 5 5 5 5 5 5 5 5 5
新疆维吾尔自治区 14 14 14 14 14 14 14 14 14

获取数据

当我们需要抓取大量数据时每次要话费很长时间,因此一次抓取所有可能需要的数据保存在本地电脑是一个不错的选择。结合cousera 上R Programming课程所学,写了一个函数,通过指定抓取的指标和地域,可以实现批量保存数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
getdata <- function(codeindex, postcode) {
for (i in codeindex) {
# 如果不存在指定文件夹则创建
if (!file.exists(i)) {dir.create(i)}
# 更改到指定文件夹
setwd(paste("./", i, sep = ""))
for (j in postcode) {
# 获取数据
tempdata <- statscnQueryData(i, dbcode = 'fsnd', moreWd = list(name = 'reg', value = j))
# 刷新数据时间跨度为20年
tempdata <- statscnQueryLastN(20)
# 保存文件
write.csv(tempdata, paste(j, ".csv", sep = ""))
}
# 退回上级文件夹
setwd("../")
}
}

处理数据

我们通过数据抓取获得了N多的数据,接下来还要通过函数来实现数据的清理。这里清理的目标是:合并一个产业分类下所有地区的数据。具体的实现形式如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
cleandata <- function(codeindex, postcode) {
for (i in codeindex) {
# 进入一个产业分类文件夹
setwd(paste("./", i, sep = ""))
# 创建一个空数据框
lsdata <- data.frame()
for (j in postcode) {
# 读取产业分类下一个地域数据
lsdata1 <- read.csv(paste(j, ".csv", sep = ""), header = FALSE)
# 转置
lsdata2 <- t(lsdata1)
# 提取变量名
rnames <- c("year",lsdata2[1,][-1])
# 转化为数据框
lsdata3 <- as.data.frame(lsdata2[-1,], row.names = 1)
# 赋值变量名
names(lsdata3) <- rnames
# 添加地域名变量
lsdata3 <- mutate(lsdata3, 地域 = j)
# 合并数据框
lsdata <- rbind(lsdata, lsdata3)
}
# 进入清洗后数据保存的文件夹
setwd("../cleaned")
# 保存文件
write.csv(lsdata, paste("cleaned", i, ".csv", sep = ""))
# 退回上一级菜单
setwd("../")
}
}

获取并清理数据

最后,我们可以指定所需要的产业代码和地域代码实现批量保存清理。例如:

1
2
3
4
datacode <- c("A0301", "A0302", ...)
postcode <- c("110000", "120000",...)
getdata(datacode, postcode)
cleandata(datacode, postcode)

对接所有文件

我们还可以通过一小段代码实现所有文件对接。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
setwd("c:/cleaned/")
# 遍历文件夹
files <- dir(getwd())
# 先提取第一个文件读取保存
files1 <- files[1]
alldata <- read.csv(files1, header = TRUE)
alldata <- alldata[,-1]
# 读取剩下的文件并合并到第一个文件
for (i in files[-1] ) {
lsdata2 <- read.csv(i, header = TRUE)
lsdata3 <- lsdata2[,-1]
alldata <- merge(alldata, lsdata3)
}
# 保存文件
write.csv(lsdata1, "dataall.csv")
# 列出前6个对象
head(lsdata1)

后记

通过两个函数大大简化了数据的获取流程,但是感觉数据清理函数虽然可以达到目的,应该还有更加简化的写法,并且应该还可以引入通道的手法,进一步增加效率。