世界各国 Top12 总储备排名

世界各国 Top12 总储备排名

前两天在微博上看到了一个视频,是一个关于世界 Top12 国家的总储备(包括黄金)排名变化的视频,然后就想模仿做一个 GIF 图。数据来源Knoema。不同于上次强硬地进行字符串处理获取数据,这次是直接把数据读取为 json 文件进行处理得到的数据。

Knoema 数据

不知怎的,现在一找国际数据就想着去 Knoema 网站上找,但是 Knoema 数据并不是很完整。

这一次用 Knoema 数据库的数据是因为想起来其返回的数据是个 json 格式的数据:

所以首先把浏览器请求到的数据 copy 一下:

然后新建一个 json 文件保存到里面去:

knoema 各国总储备数据.json

接下来就可以对这个 json 文件进行数据提取了:

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
library(jsonlite)
# 把json文件读取为一个list
json <- read_json("knoema各国总储备数据.json")
# 准备一个空数据框,等下把数据都装进去
Reserve <- data.frame(NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA)
colnames(Reserve) <- c("Time", "country", "RegionId", "series", "X.Stub", "X.Filter", "Frequency", "Value", "Unit", "Scale")
# 对年份进行循环
for(m in 1:12){
df <- data.frame(json$data[[m]]$columnData)
df<- t(df)
df <- as.data.frame(df)
row.names(df) <- NULL
# final是用来存储每年的各国数据的空数据框
final <- data.frame(NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA)
colnames(final) <- c("Time", "country", "RegionId", "series", "X.Stub", "X.Filter", "Frequency", "Value", "Unit", "Scale")
for(i in seq(from = 1, to = nrow(df), by = 10)){
j = i + 9
dftemp <- df[i:j,]
dftemp <- as.data.frame(dftemp)
dftemp <- as.data.frame(t(dftemp))
colnames(dftemp) <- c("Time", "country", "RegionId", "series", "X.Stub", "X.Filter", "Frequency", "Value", "Unit", "Scale")
final <- rbind(final, dftemp)
}; rm(i, j, dftemp, df)

final <- subset(final, !is.na(final$Time))
row.names(final) <- NULL
final$Time <- substring(final$Time, 1, 4)
Reserve <- rbind(Reserve, final)
}
rm(final, json, m)

# knoema网站上有各个国家的国旗图片,地址格式如下
Reserve$flag <- paste0("http://cdn.knoema.com/flags/normal/", tolower(Reserve$RegionId), ".png")
Reserve <- subset(Reserve, !is.na(Reserve$Time))

# 计算每年的Top12
Reserve <- Reserve[, c("Time", "country", "Value", "flag")]
Reserve$Value <- as.numeric(Reserve$Value)
da <- data.frame(Time = NA, country = NA, Value = NA, flag = NA)
for(year in Reserve$Time[!duplicated(Reserve$Time)]){
rawtemp <- Reserve[which(Reserve$Time == year),]
rawtemp <- rawtemp[order(-rawtemp$Value),]
rawtemp <- rawtemp[1:12,]
da <- rbind(da, rawtemp)
}
Reserve <- subset(da, !is.na(da$Time))
rm(da, rawtemp, year)
Reserve$Value <- Reserve$Value/100000000
Reserve$Time <- as.numeric(Reserve$Time)

Reserve$country[!duplicated(Reserve$country)]

# 为每个国家设定一个独特的颜色
Reserve$color = NA
Reserve$country <- as.character(Reserve$country)
Reserve[which(Reserve$country == "美国"),]$color <- "#2b86fb"
Reserve[which(Reserve$country == "德国"),]$color <- "#77b2f3"
Reserve[which(Reserve$country == "意大利"),]$color <- "#7fc97f"
Reserve[which(Reserve$country == "瑞士"),]$color <- "#f9de00"
Reserve[which(Reserve$country == "法国"),]$color <- "#beaed4"
Reserve[which(Reserve$country == "日本"),]$color <- "#f28a22"
Reserve[which(Reserve$country == "加拿大"),]$color <- "#fdc086"
Reserve[which(Reserve$country == "荷兰"),]$color <- "#1b9e77"
Reserve[which(Reserve$country == "比利时"),]$color <- "#d95f02"
Reserve[which(Reserve$country == "英国"),]$color <- "#7570b3"
Reserve[which(Reserve$country == "西班牙"),]$color <- "#a6cee3"
Reserve[which(Reserve$country == "奥地利"),]$color <- "#1f78b4"
Reserve[which(Reserve$country == "中国"),]$color <- "#e84238"
Reserve[which(Reserve$country == "新加坡"),]$color <- "#403ca1"
Reserve[which(Reserve$country == "大韩民国"),]$color <- "#2c5087"
Reserve[which(Reserve$country == "印度"),]$color <- "#4dc0a2"
Reserve[which(Reserve$country == "俄罗斯联邦"),]$color <- "#d474f8"
Reserve[which(Reserve$country == "沙特阿拉伯"),]$color <- "#b2df8a"
Reserve[which(Reserve$country == "墨西哥"),]$color <- "#24712f"
Reserve[which(Reserve$country == "马来西亚"),]$color <- "#fbb4ae"
Reserve[which(Reserve$country == "巴西"),]$color <- "#1950a7"
Reserve[which(Reserve$country == "泰国"),]$color <- "#4f4d87"
Reserve[which(Reserve$country == "阿尔及利亚"),]$color <- "#fb8072"

Reserve$Value <- round(Reserve$Value, 2)

然后整理得到的数据框如下:

绘图尝试

接下来就是绘图了,最开始我是试验性的绘制了一幅图,这个图是这样的:

绘制代码如下,但是这个代码里面位置的调整都是使用绝对位置,所以对其它年份的数据并不合适,所以后来循环的时候我又重新设计了代码。ggimage 包提供了一个非常炫酷的功能就是可以将图片映射到图层上。

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
library(ggplot2)
library(ggimage)
df <- data.frame("country" = c(
"中国",
"日本",
"瑞士",
"美国",
"俄罗斯",
"印度",
"韩国",
"巴西",
"新加坡",
"泰国",
"德国",
"墨西哥"),
"reserve" = c(
32356,
12641,
8110,
4512,
4327,
4126,
3888,
3739,
2850,
2025,
1999,
1754
),
"url" = c(
"http://cdn.knoema.com/flags/normal/cn.png",
"http://cdn.knoema.com/flags/normal/jp.png",
"http://cdn.knoema.com/flags/normal/ch.png",
"http://cdn.knoema.com/flags/normal/us.png",
"http://cdn.knoema.com/flags/normal/ru.png",
"http://cdn.knoema.com/flags/normal/in.png",
"http://cdn.knoema.com/flags/normal/kr.png",
"http://cdn.knoema.com/flags/normal/br.png",
"http://cdn.knoema.com/flags/normal/sg.png",
"http://cdn.knoema.com/flags/normal/th.png",
"http://cdn.knoema.com/flags/normal/de.png",
"http://cdn.knoema.com/flags/normal/mx.png"
),
"color" = c(
"#e84238",
"#f28a22",
"#f9df00",
"#2b84fc",
"#d474f8",
"#4ec0a6",
"#2c5089",
"#1950a7",
"#413ba0",
"#50498c",
"#76b2fb",
"#267330"
)
)
df$country <- factor(df$country, levels = df[order(df$reserve), ]$country)

ggplot() +
geom_bar(data = df,
aes(x = country, y = reserve,
fill = I(color), colour = I(color)),
stat = "identity") +
geom_image(data = df, aes(x = country, y = -2000, image = url), size=.05) +
geom_text(data = df, aes(x = country, y = reserve + 1500,
label = reserve, colour = color),
family = "STSongti-SC-Bold", size = 6) +
theme_bw(base_family = "STSong", base_size = 20) +
coord_flip() +
theme(plot.background = element_rect(fill = "grey90"),
axis.title.y = element_blank()) +
labs(title = "图:2018年各国总储备(包括黄金)", y = "总储备(亿美元)") +
scale_y_continuous(labels = scales::dollar_format()) +
theme(plot.margin = grid::unit(c(1, 1, 1, 1), "cm")) +
theme(panel.grid.major = element_blank()) +
theme(panel.background = element_rect(fill = "grey90")) +
theme(plot.title = element_text(hjust = 0.5))

GIF 图绘制

和之前一样,绘制 GIF 图的最好办法是先绘制一系列静态图片再合成。

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
for(year in Reserve$Time[!duplicated(Reserve$Time)]){
df <- subset(Reserve, Reserve$Time == year)
df$country <- factor(df$country, levels = df[order(df$Value), ]$country)
max <- df$Value[1] * 1.2
ggplot() +
geom_bar(data = df,
aes(x = country, y = Value,
fill = I(color), colour = I(color)),
stat = "identity") +
geom_image(data = df, aes(x = country, y = -df$Value[1] * 0.1 , image = flag), size=.05) +
geom_text(data = df, aes(x = country, y = Value + df$Value[1] * .1,
label = Value, colour = color),
family = "STSongti-SC-Bold", size = 6) +
theme_bw(base_family = "STSong", base_size = 20) +
coord_flip() +
theme(plot.background = element_rect(fill = "grey90"),
axis.title.y = element_blank()) +
labs(title = paste0("图:", year, "年各国总储备(包括黄金)"), y = "总储备(亿美元)") +
scale_y_continuous(labels = scales::dollar_format(), limits = c(-df$Value[1] * 0.1, max)) +
theme(plot.margin = grid::unit(c(1, 1, 1, 1), "cm")) +
theme(panel.grid.major = element_blank()) +
theme(panel.background = element_rect(fill = "grey90")) +
theme(plot.title = element_text(hjust = 0.5))
ggsave(paste("temp", year, ".png", sep = ""))
}

system("convert -delay 80 temp*.png 总储备.gif ")
system("rm temp*.png")

大功告成了。

世界银行数据

写这篇文章的时候我才想起来,原图表使用的是世界银行的数据啊!为啥我不去世界银行直接把数据下载下来稍许整理一下来用呢?
世界银行的数据我也下载好了:
API_FI.RES.TOTL.CD_DS2_zh_csv_v2_10226144.csv

下面的代码流程基本类似:

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# 世界银行数据
# 先手动把前面4行删除
rm(list = ls())
library(readr)
df <- read_csv("API_FI.RES.TOTL.CD_DS2_zh_csv_v2_10226144.csv")
colnames(df) <- c("country","region_id","indicator","indicator_code","1960","1961","1962","1963","1964","1965","1966","1967","1968","1969","1970","1971","1972","1973","1974","1975","1976","1977","1978","1979","1980","1981","1982","1983","1984","1985","1986","1987","1988","1989","1990","1991","1992","1993","1994","1995","1996","1997","1998","1999","2000","2001","2002","2003","2004","2005","2006","2007","2008","2009","2010","2011","2012","2013","2014","2015","2016","2017")
library(reshape2)
df <- melt(df, id.vars = c("country","region_id","indicator","indicator_code"))

df <- df[, c("country", "region_id", "variable", "value")]
df$value <- as.numeric(df$value) / 100000000
df$value <- round(df$value, 2)
df$variable <- as.numeric(as.character(df$variable))

# 只保留Top12
df2 <- data.frame(NA, NA, NA, NA)
colnames(df2) <- c("country", "region_id", "variable", "value")
for(i in 1960:2017){
dftemp <- subset(df, df$variable == i)
dftemp <- dftemp[order(-dftemp$value),]
dftemp <- dftemp[1:12,]
df2 <- rbind(df2, dftemp)
};rm(dftemp, i)
df2 <- subset(df2, !is.na(df2$country))

# 把三位国家代码转换为2位
# 国名中英文对照表.csv还是之前的那个:https://czxb.github.io/ar/国名中英文对照表.csv
id <- read.csv("国名中英文对照表.csv")
id <- id[, c("二位字母", "三位.字母")]
colnames(id) <- c("RegionID", "region_id")
df2 <- merge(df2, id, by = "region_id")

df2$flag <- paste0("http://cdn.knoema.com/flags/normal/", tolower(df2$RegionID), ".png")
Reserve <- df2[, c("country", "RegionID", "variable", "value", "flag")]
colnames(Reserve) <- c("country", "RegionID", "Time", "Value", "flag")
Reserve[!duplicated(Reserve$country),]$country
Reserve$color = NA
Reserve$country <- as.character(Reserve$country)
Reserve[which(Reserve$country == "美国"),]$color <- "#2b86fb"
Reserve[which(Reserve$country == "德国"),]$color <- "#77b2f3"
Reserve[which(Reserve$country == "意大利"),]$color <- "#7fc97f"
Reserve[which(Reserve$country == "瑞士"),]$color <- "#f9de00"
Reserve[which(Reserve$country == "法国"),]$color <- "#beaed4"
Reserve[which(Reserve$country == "日本"),]$color <- "#f28a22"
Reserve[which(Reserve$country == "加拿大"),]$color <- "#fdc086"
Reserve[which(Reserve$country == "荷兰"),]$color <- "#1b9e77"
Reserve[which(Reserve$country == "比利时"),]$color <- "#d95f02"
Reserve[which(Reserve$country == "英国"),]$color <- "#7570b3"
Reserve[which(Reserve$country == "西班牙"),]$color <- "#a6cee3"
Reserve[which(Reserve$country == "奥地利"),]$color <- "#1f78b4"
Reserve[which(Reserve$country == "中国"),]$color <- "#e84238"
Reserve[which(Reserve$country == "新加坡"),]$color <- "#403ca1"
Reserve[which(Reserve$country == "大韩民国"),]$color <- "#2c5087"
Reserve[which(Reserve$country == "印度"),]$color <- "#4dc0a2"
Reserve[which(Reserve$country == "俄罗斯联邦"),]$color <- "#d474f8"
Reserve[which(Reserve$country == "沙特阿拉伯"),]$color <- "#b2df8a"
Reserve[which(Reserve$country == "墨西哥"),]$color <- "#24712f"
Reserve[which(Reserve$country == "马来西亚"),]$color <- "#fbb4ae"
Reserve[which(Reserve$country == "巴西"),]$color <- "#1950a7"
Reserve[which(Reserve$country == "泰国"),]$color <- "#4f4d87"
Reserve[which(Reserve$country == "阿尔及利亚"),]$color <- "#fb8072"
Reserve[which(Reserve$country == "葡萄牙"),]$color <- "#a6cee3"
Reserve[which(Reserve$country == "澳大利亚"),]$color <- "#fdbf6f"
Reserve[which(Reserve$country == "委内瑞拉玻利瓦尔共和国"),]$color <- "#a6cee3"
Reserve[which(Reserve$country == "南非"),]$color <- "#1f78b4"
Reserve[which(Reserve$country == "瑞典"),]$color <- "#b2df8a"
Reserve[which(Reserve$country == "伊朗伊斯兰共和国"),]$color <- "#33a02c"

# 替换一些不好听的国名
Reserve[which(Reserve$country == "伊朗伊斯兰共和国"),]$country <- "伊朗"
Reserve[which(Reserve$country == "大韩民国"),]$country <- "韩国"
Reserve[which(Reserve$country == "俄罗斯联邦"),]$country <- "俄罗斯"
Reserve[which(Reserve$country == "沙特阿拉伯"),]$country <- "沙特"
Reserve[which(Reserve$country == "委内瑞拉玻利瓦尔共和国"),]$country <- "委内瑞拉"

for(year in 1960:2017){
df <- subset(Reserve, Reserve$Time == year)
df$country <- factor(df$country, levels = df[order(df$Value), ]$country)
max <- max(df$Value) * 1.2
ggplot() +
geom_bar(data = df,
aes(x = country, y = Value,
fill = I(color), colour = I(color)),
stat = "identity") +
geom_image(data = df, aes(x = country, y = -max(df$Value) * 0.1 , image = flag), size=.05) +
geom_text(data = df, aes(x = country, y = Value + max(df$Value) * .1,
label = Value, colour = color),
family = "STSongti-SC-Bold", size = 6) +
theme_bw(base_family = "STSong", base_size = 20) +
coord_flip() +
theme(plot.background = element_rect(fill = "grey90"),
axis.title.y = element_blank()) +
labs(title = paste0("图:", year, "年各国总储备(包括黄金)"), y = "总储备(亿美元)") +
scale_y_continuous(labels = scales::dollar_format(), limits = c(-max(df$Value) * 0.1, max)) +
theme(plot.margin = grid::unit(c(1, 1, 1, 1), "cm")) +
theme(panel.grid.major = element_blank()) +
theme(panel.background = element_rect(fill = "grey90")) +
theme(plot.title = element_text(hjust = 0.5))
ggsave(paste("temp", year, ".png", sep = ""))
}

system("convert -delay 80 temp*.png 总储备2.gif ")
system("rm temp*.png")

# R

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×