如何解决ggalluvial/ggplot2中数据不被识别的问题?
解决R语言Alluvial(桑基/冲积)图的格式报错问题
我来帮你搞定这个报错!你遇到的Data is not in a recognized alluvial form问题,核心原因是alluvial图要求每个个体(id)在所有时间点(也就是x轴的每个time类别)都有对应的状态记录,但你的原始数据是纵向的,每个id只在部分时间点有状态,缺少其他时间点的观测,完全不符合ggalluvial包对数据格式的要求。
下面是具体的解决步骤:
步骤1:补全数据格式
首先我们需要把数据补全,让每个id对应所有存在的time值,缺失的state可以标记为NA(你也可以用类似"未记录"的自定义值)。这里用tidyr包的complete()函数来快速实现:
# 先加载所需包 library(ggplot2) library(ggalluvial) library(tidyr) # 你的原始数据集 df <- data.frame( id = c(1,1,1,2,2,3,3), state = c("s_1","s_2","s_3","s_1","s_3","s_1","s_2"), time = c("t_1","t_5","t_10","t_1","t_9","t_1","t_4") ) # 补全每个id在所有time上的记录,缺失state填充为NA df_complete <- df %>% complete(id, time, fill = list(state = NA))
执行完这一步后,df_complete里每个id都会对应所有的time值,缺失的状态会被填充为NA,这样就满足alluvial图的数据格式要求了。
步骤2:调整绘图代码
接下来修改你的ggplot代码,注意几个细节:
- 因为我们补全了NA值,绘图时需要用
na.rm = TRUE忽略这些无效记录 - 如果想让流(flow)是固定的深灰色,就保留
fill = "darkgrey";如果想让流的颜色和对应状态一致,去掉这个参数即可
版本1:流为深灰色的桑基图
ggplot(df_complete, aes(x = time, stratum = state, alluvium = id, fill = state, label = state)) + geom_stratum(na.rm = TRUE) + # 忽略NA对应的层 geom_text(stat = "stratum", size = 3, na.rm = TRUE) + # 忽略NA对应的文本 geom_flow(fill = "darkgrey", color = "black", na.rm = TRUE) + # 流设置为深灰色 scale_fill_manual(values = c("s_1" = "#1f77b4", "s_2" = "#ff7f0e", "s_3" = "#2ca02c"), na.value = "white") # 给NA设置白色(不会显示,因为na.rm=TRUE)
版本2:流颜色与状态一致的桑基图
ggplot(df_complete, aes(x = time, stratum = state, alluvium = id, fill = state, label = state)) + geom_stratum(na.rm = TRUE) + geom_text(stat = "stratum", size = 3, na.rm = TRUE) + geom_flow(color = "black", na.rm = TRUE) + # 去掉fill参数,继承aes里的fill=state scale_fill_manual(values = c("s_1" = "#1f77b4", "s_2" = "#ff7f0e", "s_3" = "#2ca02c"))
为什么手册示例5可以直接用?
手册示例5的原始数据已经是每个分组在所有x轴类别上都有记录的格式(比如每个类别组合都有对应的频数),而你的数据是个体级的纵向数据,缺少了大量时间点的观测,所以必须先补全才能绘图。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

