从dplyr中的日期范围计算每年的观测值

从dplyr中的日期范围计算每年的观测值,r,dplyr,R,Dplyr,假设我有一个由行业类型、开始日期和结束日期(例如员工)组成的data.frame mydf mydf 行业开始日期结束日期 1政府2014-01-01 2020-12-01 2教育2016-02-01 2016-10-01 3军事2012-11-01 2014-01-01-01 4私营部门2013-03-01 2016-10-01 5政府2012-12-01 2015-10-01 6私营部门2011-12-01 2014-09-01 我想创建一个堆叠的ggplot条形图,其中开始日期列中的每个

假设我有一个由行业类型、开始日期和结束日期(例如员工)组成的data.frame

mydf mydf
行业开始日期结束日期
1政府2014-01-01 2020-12-01
2教育2016-02-01 2016-10-01
3军事2012-11-01 2014-01-01-01
4私营部门2013-03-01 2016-10-01
5政府2012-12-01 2015-10-01
6私营部门2011-12-01 2014-09-01
我想创建一个堆叠的ggplot条形图,其中
开始日期
列中的每个唯一年份位于X轴上(例如2011-2016年),y轴表示给定行业中该年的观察总数(行数)


我不确定操作data.frame的正确方法是什么。大概我需要对数据进行操作,以便为
行业
年份
计数
创建列。但我不确定如何从日期范围生成年份列。有什么想法吗?

将日期列转换为
date
,使用
map2
(从
purr
),
unest
列表输出,
计数
年份
并用
geom条形图绘制

library(dplyr)
library(tidyr)
library(purrr)
library(ggplot2)
mydf %>%
   mutate(across(c(start_date, end_date), as.Date)) %>% 
   transmute(industry, date = map2(start_date, end_date, seq, by = 'day')) %>% 
   unnest(c(date)) %>% 
   count(industry, year = factor(year(date))) %>%
   ggplot(aes(x = year, y = n, fill = industry)) + 
        geom_col() +
        theme_bw()
如果每个“行业”的地块应分开

mydf %>%
   mutate(across(c(start_date, end_date), as.Date)) %>% 
   transmute(industry, date = map2(start_date, end_date, seq, by = 'day')) %>% 
   unnest(c(date)) %>% 
   count(industry, year = factor(year(date))) %>%
   ggplot(aes(x = year, y = n, fill = industry)) + 
        geom_col() + 
        facet_wrap(~ industry) +
        theme_bw()
-输出


正如@IanCampbell所建议的,
seq的
by
可以是
'year'

mydf %>%
   mutate(across(c(start_date, end_date), as.Date)) %>% 
   transmute(industry, date = map2(start_date, end_date, seq, by = 'year')) %>% 
   unnest(c(date)) %>% 
   count(industry, year = factor(year(date))) %>%
   ggplot(aes(x = year, y = n, fill = industry)) + 
        geom_col() + 
        facet_wrap(~ industry) +
        theme_bw()

这就是你要找的吗? 我建议使用
purr::pmap
创建一个新的数据框架,根据原始数据的每一行,每年创建一行

我们可以使用
purrr::pmap_dfr
自动返回由行绑定的单个数据帧

我们可以使用
~和(list(…),)
技巧来按名称引用列

然后我们可以使用
dplyr::count
按列组合进行计数。那就容易了

library(dplyr)
library(purrr)
library(lubridate)
library(ggplot)
mydf %>%
  mutate(across(c(start_date, end_date), as.Date),
         start_year = year(start_date),
         end_year = year(end_date)) %>%
  pmap_dfr(~with(list(...),data.frame(industry,
                                      year = seq(start_year, end_year)))) %>%
  count(year, industry) %>%
ggplot(aes(x = year, y = n, fill = industry)) + 
  geom_bar(stat="identity")

你太棒了。我每周都从你那里学到新东西。这太完美了,谢谢!嗯,我刚刚意识到在我的实际数据集上,
unnest
步骤大量地计算了每个范围内的值的真实数量,但Ian的解决方案效果很好。我说不出为什么会这样working@Parseltongue不过我不确定。但是谢谢你分享这个信息,我想如果你把
by=
参数改成
seq
改成
'year'
,你应该很好。这很好!<代码> >(list(…)< /COD>行工作> <代码> <代码> >从基础R创建第二个参数被评估的第一个参数的环境。在这种情况下,<代码>…>代码>是由<代码> pMAP创建的一组命名参数,它包括原始数据的每一列。通过这样做,我们可以在第二个参数中按名称引用那些列。考虑<代码> PMAPHYBDL(MTCAS,~(list(…),CYL -MPG))< /C>。
library(dplyr)
library(purrr)
library(lubridate)
library(ggplot)
mydf %>%
  mutate(across(c(start_date, end_date), as.Date),
         start_year = year(start_date),
         end_year = year(end_date)) %>%
  pmap_dfr(~with(list(...),data.frame(industry,
                                      year = seq(start_year, end_year)))) %>%
  count(year, industry) %>%
ggplot(aes(x = year, y = n, fill = industry)) + 
  geom_bar(stat="identity")