如何在 R 中累积 data.frame 的多列?

how to accumulated multiple columns of a data.frame in R?

我正在尝试查找 myData 中变量 A to Z 每年的累计值。我尝试了几件事但没有成功。一旦我这样做了,我就需要计算这些年来的 maximum,minimum, median, upper and lower quartile 平均值。到目前为止,这是我费力的代码,但不知道如何进一步进行 - 事实上,当前代码也没有给我我想要的东西。

library(tidyverse)

mydate <- as.data.frame(seq(as.Date("2000-01-01"), to= as.Date("2019-12-31"), by="day"))
colnames(mydate) <- "Date"
Data <- data.frame(A = runif(7305,0,10), 
                   J = runif(7305,0,8), 
                   X = runif(7305,0,12), 
                   Z = runif(7305,0,10))
DF <- data.frame(mydate, Data)

myData <- DF %>% separate(Date, into = c("Year","Month","Day")) %>% 
   sapply(as.numeric) %>% 
   as.data.frame() %>% 
   mutate(Date = DF$Date) %>% 
   filter(Month > 4 & Month < 11) %>% 
   mutate(DOY = format(Date, "%j")) %>% 
   group_by(Year) %>% 
   mutate(cumulativeSum = accumulate(DOY))

我正在尝试为 A, J, X, Z 获取如下图。任何帮助将不胜感激。

更新(编辑)

我的问题非常混乱,所以我决定使用 excel 将其分解为多个步骤。在这里我只使用一个变量,在这种情况下是 A (注意:在我的问题中我有多个变量)。我是每年5月到10月的累积数据,反映在cumulative sum列中。在第二步 (Step-2) 中,我用他们的数据重新排列了一年中某天(5 月到 10 月)的数据。在 step-3,我正在对一年中的每一天进行我之前提到的所有年份的统计数据。我尽量澄清,但可能这是一个有点奇怪的问题。

最终图 这是我想作为本次练习的结果得出的示例图。

因此,如果我理解得很好,您正在尝试绘制 2000 年至 2019 年 5 月至 10 月之间每个变量的累积值的统计描述。

所以这是计算每个变量的第一个描述性统计数据的可能解决方案(使用dplyrlubridatetiydr 包)——我鼓励您将这段代码分成几个部分部分以便理解所有步骤。

基本上,我分离日期的月份和年份,然后将数据框转换为更长的格式,过滤以仅在感兴趣的时间段(5 月至 10 月)中保留值,计算按以下分组的值的累计总和变量和年份。然后,我创建了一个假日期(通过粘贴与真实月份和日期一致的年份),以便根据该日期和变量计算描述性统计数据。

总的来说,它给出了类似的东西:

library(lubridate)
library(dplyr)
library(tidyr)

mydata <- DF %>% mutate(Year = year(Date), Month = month(Date)) %>%
  pivot_longer(-c(Date,Year,Month), names_to = "variable", values_to = "values") %>% 
  filter(between(Month,5,10)) %>% 
  group_by(Year, variable) %>% 
  mutate(Cumulative = cumsum(values)) %>%
  mutate(NewDate = ymd(paste("2020", Month,day(Date), sep = "-"))) %>%
  ungroup() %>%
  group_by(variable, NewDate) %>%
  summarise(Median = median(Cumulative),
            Maximum = max(Cumulative),
            Minimum = min(Cumulative),
            Upper = quantile(Cumulative,0.75),
            Lower = quantile(Cumulative, 0.25))

然后,您可以通过执行以下操作获得与您的示例类似的情节:

library(ggplot2)
ggplot(mydata, aes(x = NewDate))+
  geom_ribbon(aes(ymin = Lower, ymax = Upper), color = "grey", alpha =0.5)+
  geom_line(aes(y = Median), color = "darkblue")+
  geom_line(aes(y = Maximum), color = "red", linetype = "dashed", size = 1.5)+
  geom_line(aes(y = Minimum), color ="red", linetype = "dashed", size = 1.5)+
  facet_wrap(~variable, scales = "free")+
  scale_x_date(date_labels = "%b", date_breaks = "month", name = "Month")+
  ylab("Daily Cumulative Precipitation (mm)")

它看起来像你想要达到的目标吗?


编辑:添加图例

在这里添加图例并不容易,因为您使用的是具有不同颜色、形状的不同 geom(色带、线条)...

因此,一种方法是重新组合可以使用相同 geom 绘制的统计数据并执行:

mydata %>% pivot_longer(cols = c(Median, Minimum,Maximum), names_to = "Statistic",values_to = "Value") %>%
  ggplot(aes(x = NewDate))+
  geom_ribbon(aes(ymin = Lower, ymax = Upper, fill = "Upper / Lower"), alpha =0.5)+
  geom_line(aes(y = Value, color = Statistic, linetype = Statistic, size = Statistic))+
  facet_wrap(~variable, scales = "free")+
  scale_x_date(date_labels = "%b", date_breaks = "month", name = "Month")+
  ylab("Daily Cumulative Precipitation (mm)")+
  scale_size_manual(values = c(1.5,1,1.5))+
  scale_linetype_manual(values = c("dashed","solid","dashed"))+
  scale_color_manual(values = c("red","darkblue","red"))+
  scale_fill_manual(values = "grey", name = "")

所以,它看起来不错,但如您所见,它有点奇怪,因为 Upper/Lower 稍微偏离了主要图例。

另一个解决方案是添加图例作为最后日期的标签。为此,您可以通过仅对第一个数据框的最后日期进行子集化来创建第二个数据框:

mydata_label <- mydata %>% filter(NewDate == max(NewDate)) %>% 
  pivot_longer(cols = Median:Lower, names_to = "Stat",values_to = "val")

然后,在不改变绘图部分的情况下,您可以:

ggplot(mydata, aes(x = NewDate))+
  geom_ribbon(aes(ymin = Lower, ymax = Upper), alpha =0.5)+
  geom_line(aes(y = Median), color = "darkblue")+
  geom_line(aes(y = Maximum), color = "red", linetype = "dashed", size = 1.5)+
  geom_line(aes(y = Minimum), color ="red", linetype = "dashed", size = 1.5)+
  facet_wrap(~variable, scales = "free")+
  scale_x_date(date_labels = "%b", date_breaks = "month", name = "Month", limits = c(min(mydata$NewDate),max(mydata$NewDate)+25))+
  ylab("Daily Cumulative Precipitation (mm)")+
  geom_text(data = mydata_label, 
            aes(x = NewDate+5, y = val, label = Stat, color = Stat), size = 2, hjust = 0, show.legend = FALSE)+
  scale_color_manual(values = c("Median" = "darkblue","Maximum" = "red","Minimum" = "red","Upper" = "black", "Lower" = "black"))

由于 space 问题,我故意缩小了文本标签的大小,以便您可以看到所有这些问题。但是根据你附在问题上的数字,你应该有足够的 space 来让它工作。