如何可视化 "stepwise" 成分随时间的变化

How to visualize "stepwise" change of composition over time

我有一个 data.frame 包含选举年议会中各政党之间的席位分配情况。 最终,我想获得一个类似于此 one 的图表。我想形象化历年议会的组成,而不仅仅是选举年。

results<-structure(list(party = c("PARTY1", "PARTY1", "PARTY1", "PARTY1", "PARTY2", "PARTY2", 
"PARTY2", "PARTY2", "PARTY2", "PARTY2", "PARTY3", "PARTY3", "PARTY3", "PARTY3", "PARTY3", 
"PARTY3", "PARTY3", "PART4", "PART4", "PART4", "PART4"), year = c(1996, 
1998, 2000, 2010, 1996, 2000, 2002, 2006, 2010, 2014, 1996, 1998, 
2000, 2002, 2006, 2010, 2014, 2002, 2006, 2010, 2014), party.seats = c(8, 
6, 5, 3, 19, 8, 10, 9, 7, 10, 9, 4, 6, 5, 3, 4, 5, 3, 7, 8, 6
)), class = "data.frame", row.names = c(NA, -21L), .Names = c("party", 
"year", "party.seats"))

我可以制作条形图,但它只显示选举年的数据,而错过了两次选举之间的年份。

ggplot(data=results,aes(x=as.factor(year), y=party.seats, fill=party, label=party))+geom_bar(stat="identity")

我可以用 geom_area 制作一个 ggplot 图表,但是它具有误导性,因为它表明席位的分布在选举后的几年中正在发生变化(有倾斜,而不是“步骤”).

ggplot(as.data.frame(xtabs(party.seats~year+party, results)), aes(x=as.Date(as.character(year), "%Y"), y = Freq, fill = party)) +  geom_area(position = "stack")

有什么帮助吗?我特别想知道是否有一个(与时间序列相关的?)命令可以将选举年的结果带到所有随后的年份,直到举行新的选举。所以基本上,一个命令将时间 x 的选举事件视为正在进行(= 填充之间的年份),直到在时间 y 举行新的选举。

我认为 geom_step 是您正在寻找的,尽管最简单的实现不会将 bars/areas 堆栈与分配的席位总数相加(尽管这可能更好):

ggplot(data=results
      , aes(x=year
            , y=party.seats
            , col=party)) +
  geom_step()

如果你真的想要,你可以获得填充,但就像@Haboryme 的回答一样,你需要在两次选举之间生成所有点数。在这里,我使用 dplyr/tidyr 为选举之间的每一天添加一个新数据行(您只需要足够窄的分辨率以使 "step" 出现在瞬间而不是分布在一整年在最后的情节上)在最近的选举之后添加了一些以使这些值实际显示出来。然后我从之前到下一次选举填补党的席位,并将缺失设置为 0 以备不时之需(在党有任何席位之前)。

请注意,您可以使用确切的选举日期而不是年份来扩展它,而无需修改太多

results %>%
  complete(year = full_seq(c(min(year), max(year) + 1), 1/365), party) %>%
  group_by(party) %>%
  fill(party.seats) %>%
  replace_na(replace = list(party.seats = 0)) %>%
  ggplot(
    aes(x=year
        , y=party.seats
        , fill=party)) +
  geom_area(position = "stack")

给予

尽管如此,我还是更喜欢这些线条,因为当它们没有堆叠在一起时,更容易将它们相互比较。比如2010年到2014年,从地区版本上很难判断是党2席位多还是党党4席位多(但从台词上看就很清楚了)。

另一种选择是创建包含所有缺失年份的完整数据框:

library(tidyverse)                      
library(zoo)
all_years=seq(min(results$year),max(results$year)) #get the sequence of all the years considered
filled=data.frame(party=rep(unique(results$party),each=length(all_years)), #build a df with the seq of years for each party
                  year=rep(all_years,length(unique(results$party))))

然后与您的数据合并并填充 NA(如果开头为 0,否则为最新值):

df=merge(results,filled,by.y=c("party","year"),all.y=T)%>%
  group_by(party)%>%
  na.locf()%>%
  mutate(party.seats=coalesce(as.numeric(party.seats), 0))  

geom_barwidth=1 绘图以获得看起来连续的东西:

ggplot(data=df,aes(x=as.factor(year), y=party.seats, fill=party, label=party))+
  geom_bar(stat="identity",width = 1)

它给出(x 轴需要一些调整):

你也可以尝试花式 streamgraph(你也会得到 plotly 之类的 mouse-hover 工具提示):

library(dplyr)
library(streamgraph)
results %>%
  streamgraph("party", "party.seats", "year") %>%
  sg_axis_x(1, "year", "%Y") %>%
  sg_legend(TRUE, "party")

results %>%
  streamgraph("party", "party.seats", "year", offset="zero", interpolate="step") %>%
  sg_axis_x(1, "year", "%Y") %>%
  sg_fill_brewer("PuOr")