有解決方法,但它看起來像你可能有每個狀態的這些值,用方面來組織它們。在這種情況下,我們儘量將其設置爲「tidy」。在這個構建的假數據中,爲了簡單起見,我更改了變量名稱,但概念是相同的。
library(dplyr)
library(purrr)
library(ggplot2)
temp.grp <- expand.grid(state = sample(state.abb, 8), year = 2008:2015) %>%
# sample 8 states and make a dataframe for the 8 years
group_by(state) %>%
mutate(sval = cumsum(rnorm(8, sd = 2))+11) %>%
# for each state, generate some fake data
ungroup %>% group_by(year) %>%
mutate(nval = mean(sval))
# create a "national average" for these 8 states
head(temp.grp)
Source: local data frame [6 x 4]
Groups: year [1]
state year sval nval
<fctr> <int> <dbl> <dbl>
1 WV 2008 15.657631 10.97738
2 RI 2008 10.478560 10.97738
3 WI 2008 14.214157 10.97738
4 MT 2008 12.517970 10.97738
5 MA 2008 9.376710 10.97738
6 WY 2008 9.578877 10.97738
這繪製了兩個帶,一個是全國平均水平,並取其較小者,全國平均水平或狀態值線之間。這意味着,當全國平均水平較低時,它實際上是一個高度爲零的帶。當全國平均水平較高時,帶狀區位於全國平均值和較低的州值之間。
另一個功能區與此相反,當狀態值較小時爲0高度,狀態值較高時在兩個值之間伸展。
ggplot(temp.grp, aes(year, nval)) + facet_wrap(~state) +
geom_ribbon(aes(ymin = nval, ymax = pmin(sval, nval), fill = "State lower")) +
geom_ribbon(aes(ymin = sval, ymax = pmin(sval, nval), fill = "State higher")) +
geom_line(aes(linetype = "Nat'l Avg")) +
geom_line(aes(year, sval, linetype = "State")) +
scale_fill_brewer(palette = "Set1", direction = -1)
這主要工作,但你可以看到,這是一個有點古怪的交叉點上發生的,因爲他們沒有在今年的x值恰好跨越:
要解決這個問題,我們需要沿着每條線段進行插值,直到這些間隙與眼睛無法區分爲止。我們將爲此使用purrr::map_df
。我們首先將split
的數據放入一個數據幀列表中,每個狀態一個。然後我們沿着該列表map
,創建1)插值年份和狀態值,2)插值年份和國家平均值,以及3)每個狀態的標籤。
state.x state.y nat.x nat.y state
1 2008.000 15.65763 2008.000 10.97738 WV
2 2008.089 15.90416 2008.089 11.03219 WV
3 2008.177 16.15069 2008.177 11.08700 WV
4 2008.266 16.39722 2008.266 11.14182 WV
5 2008.354 16.64375 2008.354 11.19663 WV
6 2008.443 16.89028 2008.443 11.25144 WV
的approx
功能默認返回一個名爲x
和y
名單,但我們把它強制轉換爲數據框,並使用state =
和nat =
參數重新標記它。請注意,插入的年份在每行中都是相同的值,所以我們可以在此處拋出其中一列。我們也可以重新命名這些列,但我會保留它。
現在我們可以修改上面的代碼來使用這個新創建的插值數據框。
ggplot(aes(nat.x, nat.y)) + facet_wrap(~state) +
geom_ribbon(aes(ymin = nat.y, ymax = pmin(state.y, nat.y), fill = "State lower")) +
geom_ribbon(aes(ymin = state.y, ymax = pmin(state.y, nat.y), fill = "State higher")) +
geom_line(aes(linetype = "Nat'l Avg")) +
geom_line(aes(nat.x, state.y, linetype = "State")) +
scale_fill_brewer(palette = "Set1", direction = -1)
現在的路口是乾淨多了。此解決方案的解決方案由approx(...)
的兩個調用的n =
參數控制。
https://stackoverflow.com/a/37979793/3330437 – Brian
感謝您的鏈接,@布賴恩。但是該解決方案不起作用。使用該答案中的方法繪製線條時,陰影區域甚至不會出現。我的兩條線都是黑色的。 – AldoTheApache