计算给定的开始日期和结束日期之间每个季度的平均价格?

时间:2016-09-13 09:53:48

标签: r date date-range

我需要你的帮助,因为我自己没有得到正确的结果。

我的数据看起来有点像:

product startdate    enddate     city     cost   double
  1    1999-01-03  2001-02-01   Boston      8       0
  2    2000-07-06  2001-11-24   New York   10,5     0
...

我想要的是一张表格,显示平均成本除以城市和季度。

到目前为止我做了什么:

df <- read_csv2("mydata.csv")

#subset data
double <- df$double
df2 <- subset(df,double==0)


#date class
startdate <- strptime(df2$startdate,format="%Y-%m-%d")

library(zoo)
quarter <- as.yearqtr(startdate,"%Y-%m-%d")


table <- tapply(cost,list(df2$city,quarter),mean)

我得到的表可能看起来像这样:

City       2011 Q1 2011 Q2 2011 Q3
New York     10     11,2    11,7
Boston       9       9,5    9,9

我的问题是我有一个开始日期和结束日期。该表显示了依赖于startdate的季度。 我现在想要获得相同的表,但季度应该包括enddates。这意味着:如果startdate是2006-01-01,enddate是2006-08-01我的项目在2006年第一季度,2006年第二季度,2006年第三季度在线。 我的商品价格在整个时间内是相同的,但是当我计算每个季度的平均价格时,价格应该包含在产品上线的每个季度中。

我所做的是更改enddate类:

#enddate , date class
today <- Sys.Date()
df2[["enddate"]][is.na(df2[["enddate"]])] <- today
enddate <- strptime(df2$enddate,format="%Y-%m-%d")

现在我已经尝试过一些事情,例如处理日期间隔和剪切日期,但这根本不起作用。

感谢您的任何提示!

2 个答案:

答案 0 :(得分:2)

您的完整解决方案可能如下所示。我使用过data.table。

在data.table中加载数据

library(data.table)
d <- read.csv("Products.csv")
D <- as.data.table(d)

调整数据以适当处理日期并计算财务季度。

# Condition data
#   Format date columns to Date objects
D[, ':=' (Date.Start = as.Date(Date.Start, format="%d-%b-%y"),
  Date.End = as.Date(Date.End, format="%d-%b-%y"))][]
#   Compute the no. of quarters from start, end dates
#     Use:
#       getSeriesV() for dates every quarter given start and end dates
#       getQuarterV() for the fiscal quarter given a date
Quarters <- D[, .(getSeriesV(Date.Start, Date.End))]
Quarters <- lapply(Quarters$V1, function(x) unique(getQuarterV(x)))

以长格式展开data.table,以包含财政季度的信息。

Repeats <- sapply(Quarters, length)
Names <- D[, rownames(.SD)]
de <-  d[rep(Names, Repeats),]
De <- as.data.table(de)
De[, ':=' (Date.Start = as.Date(Date.Start, format="%d-%b-%y"),
           Date.End = as.Date(Date.End, format="%d-%b-%y"))][]
De[, Quarters := unlist(Quarters)]

分析摘要数据。

De[, .(Avg = mean(Cost)), by=c('Product', 'City', 'Quarters')]

我从数据开始

Product,Date.Start,Date.End,City,Cost
Apple,1-Jan-16,1-Aug-16,Bangalore,150
Tomato,1-Dec-15,15-Jan-16,Pune,30
Apple,1-Nov-15,1-Jun-16,Bangalore,155
Tomato,1-Jun-16,1-Dec-16,Bangalore,45
Tomato,1-Oct-16,1-Nov-16,Pune,15

答案 1 :(得分:1)

一种策略是在财政年度的四分之一时间内使用额外的信息(即列)扩展您的表格。然后,您可以按照您想要的方式进行汇总。

要获得年份和季度,请使用类似

的功能
getQuarter <- function(x, first=0, prefix="Q") {
  # x:      Date object 
  # first:  Jan is 0
  # prefix: Affix symbol for quarter, default 'Q' 
  d <- as.POSIXlt(x);
  q <- floor((d$mon-first+1)/3.03)
  q <- paste0(d$year+1900,'-',prefix,q+1, collapse="")
  q
}

试一试:

start <- as.Date("01-01-16", format="%d-%m-%y")
end <- as.Date("01-09-16", format="%d-%m-%y")
getQuarter(start)   # "2016-Q1"
getQuarter(end)     # "2016-Q3"

然后像这样矢量化。

getQuarterV <- Vectorize(getQuarter)
getQuarterV(c(start, end))   # "2016-Q1" "2016-Q3"

要获得开始日期和结束日期之间的所有季度,请使用类似

的功能
getSeries <- function(start, end) {
  # start:  Date object
  # end:    Date object
  s <- seq(from=start, to=end, by="3 months")
  s <- c(s, end)
  unique(s)
}

试一试:

getSeries(start, end)     # "2016-01-01" "2016-04-01" "2016-07-01" ..
getSeries(start, start)   # "2016-01-01"

现在把它放在一起以获得两个日期之间的所有季度。

unique(getQuarterV(getSeries(start, end)))   # "2016-Q1" "2016-Q2" "2016-Q3"

现在,您可以继续将此数据与原始数据集成,并提取所需的摘要。

相关问题