如何在活跃的年份中传播项目?

时间:2017-04-07 14:03:54

标签: sql r excel excel-2013

我有一个包含超过10000个项目的Excel电子表格,每个项目的开始日期和结束日期都不同。我需要在他们活跃的几年中分散项目,以便按年计算确切的数量。从这个例子开始我该怎么做?

start date   end date     entityNo  amount
4/1/2001     8/31/2012      1         500
1/1/2005     12/31/2007     2         100

我最初想到的解决方案是在Excel中获取开始日期和结束日期(结束日期 - 开始日期+ 1)之间的差异,这样我就可以获得每个项目的持续时间。在获得天数(例如4100天)之后,我将持续时间除以一年中的总天数(365.25天),这将给出我的年份范围但是当我将每个项目分配到正确的年份。

超过10,000个项目的数据集的预期输出:

start date   end date         no of years  entityNo  amount
4/1/2001     8/31/2012                11            1         500
2002
2003
2004
2005
2006
2007 upto 8/31/2012

后跟另一个具有不同实体编号的项目

start date       end date      entity no      amount
   1/1/2005     12/31/2007     2              100

输出

years       entity no     amount
1/1/2005    2             100
2006        2             100
2/31/2007   2             100

2 个答案:

答案 0 :(得分:0)

此解决方案需要r包lubridate

library(tidyverse)
library(lubridate)

# Create example data frame
dat <- tribble(
  ~`start date`, ~`end date`, ~`entityNo`, ~`amount`,
  "4/1/2001",  "8/31/2012",   1,         500,
  "1/1/2005",  "12/31/2007",  2,         100
)

dat %>%
  mutate(`start date` = mdy(`start date`), `end date` = mdy(`end date`)) %>%
  mutate(`start year` = year(`start date`), `end year` = year(`end date`)) %>%
  mutate(`no of years` = `end year` - `start year`) %>%
  select(`start date`, `end date`, `no of years`, entityNo, amount)

或者你可以使用一些字符串操作方法。

dat %>%
  mutate(`no of years` = as.numeric(substring(`end date`, nchar(`end date`) - 3)) -
           as.numeric(substring(`start date`, nchar(`start date`) - 3))) %>%
  select(`start date`, `end date`, `no of years`, entityNo, amount)

答案 1 :(得分:0)

根据最新的编辑,OP希望按日历年划分每个项目的持续时间。这可以通过使用foverlaps()包的data.table函数来完成。

读取数据

library(data.table)
projects <- fread(
"start_date   end_date     entityNo  amount
4/1/2001     8/31/2012      1         500
1/1/2005     12/31/2007     2         100")

fread()可用于从磁盘快速读取csv个文件。这里使用了一个便利功能,它允许从字符变量中读取数据。

准备数据

library(lubridate)
# convert dates from character to Date class
date_cols <- c("start_date", "end_date")
projects[, (date_cols) := lapply(.SD, mdy), .SDcols = date_cols]

# compute duration of project = number of years in which project was active
projects[, years_active := year(end_date) - year(start_date) + 1]

请注意,years_active与OP提供的no of years不同。 years_active是传播数据所需的行数。

创建计算重叠的日期范围

date_range <- projects[, .(year = seq(year(min(start_date)), 
                                      year(max(end_date))))]
date_range[, start_in_year := ymd(paste0(year, "-01-01"))]
date_range[, end_in_year := ymd(paste0(year, "-12-31"))]
setkey(date_range, start_in_year, end_in_year)

date_range
#    year start_in_year end_in_year
# 1: 2001    2001-01-01  2001-12-31
# 2: 2002    2002-01-01  2002-12-31
# 3: 2003    2003-01-01  2003-12-31
# ...
#10: 2010    2010-01-01  2010-12-31
#11: 2011    2011-01-01  2011-12-31
#12: 2012    2012-01-01  2012-12-31

请注意,此方法可以扩展为按季度,月份,ISO周或天数创建持续时间细分。

计算重叠间隔

projects_by_year <- foverlaps(projects, date_range, by.x = date_cols)
# adjust start_in_year to coincide with project start date
projects_by_year[, start_in_year := pmax(start_in_year, start_date)]
# adjust end_in_year to coincide with project end date
projects_by_year[, end_in_year := pmin(end_in_year, end_date)]

projects_by_year
#    year start_in_year end_in_year start_date   end_date entityNo amount years_active
# 1: 2001    2001-04-01  2001-12-31 2001-04-01 2012-08-31        1    500           12
# 2: 2002    2002-01-01  2002-12-31 2001-04-01 2012-08-31        1    500           12
# 3: 2003    2003-01-01  2003-12-31 2001-04-01 2012-08-31        1    500           12
# ...
#10: 2010    2010-01-01  2010-12-31 2001-04-01 2012-08-31        1    500           12
#11: 2011    2011-01-01  2011-12-31 2001-04-01 2012-08-31        1    500           12
#12: 2012    2012-01-01  2012-08-31 2001-04-01 2012-08-31        1    500           12
#13: 2005    2005-01-01  2005-12-31 2005-01-01 2007-12-31        2    100            3
#14: 2006    2006-01-01  2006-12-31 2005-01-01 2007-12-31        2    100            3
#15: 2007    2007-01-01  2007-12-31 2005-01-01 2007-12-31        2    100            3

项目1分布在12年/每年,预计2年超过3年。调整start_in_yearend_in_year以匹配每个项目的respctive开始和结束中的正确开始和结束日期

希望这是预期的结果。

按年度计算聚合

长格式非常适合每年计算聚合。例如,每年的项目数量:

projects_by_year[, .N, by = year]
#    year N
# 1: 2001 1
# 2: 2002 1
# 3: 2003 1
# 4: 2004 1
# 5: 2005 2
# 6: 2006 2
# 7: 2007 2
# 8: 2008 1
# 9: 2009 1
#10: 2010 1
#11: 2011 1
#12: 2012 1

或每年的总金额:

projects_by_year[, sum(amount), by = year]
#    year  V1
# 1: 2001 500
# 2: 2002 500
# 3: 2003 500
# 4: 2004 500
# 5: 2005 600
# 6: 2006 600
# 7: 2007 600
# 8: 2008 500
# 9: 2009 500
#10: 2010 500
#11: 2011 500
#12: 2012 500