首先,加载recharts
:
library(recharts)
和弦图Chord plot包含2个类型:
关键是:
rbind
将两者合并。如果未提供节点数据框,recharts会基于联结数据框自动构建。相应地,提供[x, x1, series/relation, weight/value]数据框。echartr(data, x, <y>, <series>, <t>, <type>, <subtype>)
参数 | 要求 |
---|---|
data |
数据框格式的源数据 |
x |
文本型自变量,其他类型转为因子后计算。节点/联结模式下,必须提供 |
y |
数值型应变量。节点/联结模式下,只传入 |
series |
数据系列变量,转为因子后计算。如果提供多个变量,只传入第一个。 |
t |
时间轴变量,转为因子后计算。如提供多个变量,只传入第一个。 |
type |
‘chord’. |
subtype |
|
grpmtx <- matrix(c(11975, 5871, 8916, 2868, 1951, 10048, 2060, 6171, 8010, 16145,
8090, 8045, 1013, 990, 940, 6907), byrow=TRUE, nrow=4)
grpmtx <- as.data.frame(grpmtx)
names(grpmtx) <- paste0('Group', 1:4)
grpmtx$Name <- paste0('Group', 1:4)
knitr::kable(grpmtx, align=c('lllll'))
Group1 | Group2 | Group3 | Group4 | Name |
---|---|---|---|---|
11975 | 5871 | 8916 | 2868 | Group1 |
1951 | 10048 | 2060 | 6171 | Group2 |
8010 | 16145 | 8090 | 8045 | Group3 |
1013 | 990 | 940 | 6907 | Group4 |
数据框的前四列就是一个矩阵,而最后一列则是名称向量。所以其数据结构符合矩阵模式的要求。
矩阵模式可以转换为节点/联结模式。Matrix[i, j]代表了两个节点(i & j)和一个联结(i -> j)。
knitr::kable(deutsch[deutsch$year==2014,])
player | club | weight | role | year |
---|---|---|---|---|
Kruse | Monchengladbach | 1 | Fw | 2014 |
Kramer | Monchengladbach | 1 | Mf | 2014 |
Neuer | Bayern | 1 | Gk | 2014 |
Boateng | Bayern | 1 | Df | 2014 |
Lahm | Bayern | 1 | Df | 2014 |
Kroos | Bayern | 1 | Mf | 2014 |
Muller | Bayern | 1 | Mf | 2014 |
Gotze | Bayern | 1 | Fw | 2014 |
Badstuber | Bayern | 1 | Df | 2014 |
Hummels | Dortmund | 1 | Df | 2014 |
Weidenfeller | Dortmund | 1 | Gk | 2014 |
Reus | Dortmund | 1 | Df | 2014 |
Gundogan | Dortmund | 1 | Md | 2014 |
数据框内找不到数值型矩阵结构,所以被识别为节点/联结模式。由于第一、二列么有NA,所以recharts
会基于所给的数据框构建一个节点数据框。其结构为:
name | value | series |
---|---|---|
Badstuber | 1 | |
Boateng | 1 | |
Gotze | 2 | |
Gundogan | 1 | |
Howedes | 1 | |
Hummels | 2 | |
Kimmich | 1 | |
Kramer | 1 | |
Kroos | 2 | |
Kruse | 1 | |
Lahm | 1 | |
Leno | 1 | |
Meyer | 1 | |
Muller | 2 | |
Mustafi | 1 | |
Neuer | 2 | |
Ozil | 1 | |
Reus | 1 | |
Tah | 1 | |
Volland | 1 | |
Weidenfeller | 1 | |
Arsenal | 2 | |
Bayern | 11 | |
Dortmund | 5 | |
Leverkusen | 3 | |
Madrid | 1 | |
Monchengladbach | 2 | |
Schalke | 2 |
设type
为’chord’,subtype
为’ribbon’。
echartr(grpmtx, Name, c(Group1, Group2, Group3, Group4),
type='chord', subtype='ribbon + asc + descsub + hidelab + scaletext') %>%
setTitle('Test Data','From d3.js')
设type
为’chord’。如果数据结构不包括双向联结,不论是否设置subtype
为’ribbon’,都无法显示缎带和弦图。
echartr(deutsch[deutsch$year==2014,], c(club, player), weight, role, type='chord',
sub='asc + descsub + rotatelab') %>%
setTitle('Club Orientation of Deutsch Soccer Team (2014)')
如果要显示缎带和弦图,必须将源数据修改为双向联结。
现在,deutsch14
只有单向联结,这意味着,它只定义了Gotze->Bayern的关系,而没有定义反向的Bayern->Gotze。
knitr::kable(with(deutsch[deutsch$year==2014,], table(player, club)))
Bayern | Dortmund | Monchengladbach | |
---|---|---|---|
Badstuber | 1 | 0 | 0 |
Boateng | 1 | 0 | 0 |
Gotze | 1 | 0 | 0 |
Gundogan | 0 | 1 | 0 |
Hummels | 0 | 1 | 0 |
Kramer | 0 | 0 | 1 |
Kroos | 1 | 0 | 0 |
Kruse | 0 | 0 | 1 |
Lahm | 1 | 0 | 0 |
Muller | 1 | 0 | 0 |
Neuer | 1 | 0 | 0 |
Reus | 0 | 1 | 0 |
Weidenfeller | 0 | 1 | 0 |
我们需要复制source和target列以构建一个矩阵。
deutsch14 <- deutsch[deutsch$year==2014,]
deutsch14 <- rbind(deutsch14, deutsch14)
deutsch14[14:26, c('player', 'club')] <- recharts:::exchange(
deutsch14[14:26, 'player'], deutsch14[14:26, 'club'])
knitr::kable(with(deutsch14, table(player, club)))
Badstuber | Bayern | Boateng | Dortmund | Gotze | Gundogan | Hummels | Kramer | Kroos | Kruse | Lahm | Monchengladbach | Muller | Neuer | Reus | Weidenfeller | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Badstuber | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Bayern | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 |
Boateng | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Dortmund | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
Gotze | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Gundogan | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Hummels | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Kramer | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
Kroos | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Kruse | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
Lahm | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Monchengladbach | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
Muller | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Neuer | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Reus | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Weidenfeller | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
这样,设置subtype
为’ribbon’,就能获得缎带和弦图了。
echartr(deutsch14, c(club, player), weight, role, type='chord',
sub='asc + descsub + rotatelab + ribbon') %>%
setTitle('Club Orientation of Deutsch Soccer Team (2014)')
另一个例子基于预置的数据集mideast。
mideast <- as.data.frame(mideast, col.names=mideast[1,], stringsAsFactors=FALSE)
names(mideast) <- mideast[1,]
mideast <- mideast[2:16,]
me <- data.table::melt(mideast, id=NA)
## Warning in melt_dataframe(data, as.integer(id.ind - 1),
## as.integer(measure.ind - : '.Random.seed' is not an integer vector but of
## type 'NULL', so ignored
me <- me[!is.na(me$value),]
me$series <- strsplit(me$value, '/')
me$value <- sapply(me$series, function(x) as.numeric(x[2]))
me$series <- sapply(me$series, function(x) x[1])
names(me) <- c('source', 'target', 'value', 'series')
str(me)
## 'data.frame': 82 obs. of 4 variables:
## $ source: chr "叙利亚反对派" "阿萨德" "伊朗" "塞西" ...
## $ target: Factor w/ 15 levels "美国","叙利亚反对派",..: 1 1 1 1 1 1 1 1 2 2 ...
## $ value : num 1 1 1 1 1 1 1 1 9 9 ...
## $ series: chr "支持" "反对" "反对" "未表态" ...
echartr(me, c(source, target), value, series, type='chord', sub='ribbon')
用year
列作为时间轴。
echartr(deutsch, c(club, player), weight, role, t=year, type='chord',
sub='asc + descsub + rotatelab') %>%
setTimeline(show=FALSE, autoPlay=TRUE) %>%
setTitle('Club Orientation of Deutsch Soccer Team')
接下来可以配置控件、添加标注点/标注线,以及美化成图。
参考相关函数,尽情探索吧。