我有一个带有时间点(a,b和c),标签(l1,l2,l3)的数据帧,以及在时间点和标签上分布的频率。 我想用R中的ggalluvial包创建一个sankey图。 这是一些代码:
library(tidyverse)
library(forcats)
library(ggalluvial)
library(magrittr)
plotAlluvial <- function(.df,name=freq) {
y_name <- enquo(name)
ggplot(.df,
aes(
x = tp,
stratum = lbl,
alluvium = id,
label=lbl,
fill = lbl,
y=!!y_name
)
) +
geom_stratum() +
geom_flow(stat = "flow", color = "darkgray") +
geom_text(stat = "stratum") +
scale_fill_brewer(type = "qual", palette = "Set2")
}
x1=c(6,0,0,5,5,4,2,0,3)
x2=c(5,5,3,0,0,5,0,7,0)
df=data_frame(tp1=rep(c('a','b'),each=9),
lbl1=c(rep(c('l1','l2','l3'),2,each=3)),
tp2=rep(c('b','c'),each=9),
lbl2=c(rep(c('l1','l2','l3'),6)),
freq=c(x1,x2)
)
df2=df %>%
mutate(id=row_number()) %>%
unite(un1,c(tp1,lbl1)) %>%
unite(un2,c(tp2,lbl2)) %>%
tidyr::gather(key,value,-c(freq,id)) %>%
separate('value',c('tp','lbl'))
df2.left= df2 %>%
dplyr::filter(!(key=='un1' & tp=='b'))
df2.right= df2 %>%
dplyr::filter(!(key=='un2' & tp=='b'))
我可以在想要的图的左侧和右侧进行绘制:
plotAlluvial(df2.left)
plotAlluvial(df2.right)
但是,如果我尝试同时绘制左侧和右侧,则会得到以下绘图:
plotAlluvial(df2)
当我使用上面的代码时,图的图在时间点b的频率过多。层应与其他两个层一样高,因此高度为25。 我究竟做错了什么?如何创建将前两个图结合在一起的图?
编辑:
在评论后,我添加了一部分频率变量。现在,层b具有正确的高度,但是在时间点b,流入和流出的流量仍仅占每种情况的50%。
df2 %<>% group_by(tp) %>% mutate(prop = freq / sum(freq)) %>%
ungroup()
plotAlluvial(df2,prop)