时间序列为data.table中的`ts`列?

时间:2014-07-25 14:43:31

标签: r time-series data.table

我有多组时间序列数据,希望帮助找出将它们放入R并用R分析它们的最佳方法。我非常熟悉data.table但不太熟悉R&#39 ; s ts课程支持时间序列分析。

特别是,我想知道在这种情况下如何使用ts ts中是否存在限制(例如聚合一组{{1}的问题使它适合在这里使用。

数据

有很多商店。对于每个商店,我每天都有多个数据点,例如以美元计的销售量,交易数量的销售量和商店流量(进入商店的人数)。 (实际上我所拥有的是一个包含列存储ID,日期以及该商店和日期数据的表。)

我一直在做的是使用每个商店一行的data.table,按商店将数据汇总到几个月,并将每个月的值存储在一个单独的命名列中(例如jan14_dollars,feb14_dollars ... )但由于很多原因,这是笨拙的,特别是当我想看几周或几周时。

我认为处理此问题的正确方法是使ts类型的列,以便每行只是ts但是(a)如何将数据转换为该格式( b)可以store, dollars_ts, transactions_ts, traffic_ts组合整数的方式来给我我想要的结果吗? 如果您只能回答(a)或(b)但不能回答两者,请尽量回答。

我无法提供逼真的数据集,但您可以生成一个随机的数据集:

ts

分析

我想回答诸如"有多少商店的美元销售增长为正的问题?"和"美元/交易的变化与流量变化之间是否存在关系?"并将数据分成时间段并比较各时段的答案(例如今年的Q1与去年的Q1)。

可以使用ts来回答这些问题吗?如果是这样,我如何将这些数据放入一组适当的列中,或者我应该使用除require("data.table") storeData <- CJ(store = toupper(letters), date = seq(as.Date('2012-01-01'), as.Date('2014-01-01'), by="day")) storeData$dollars = sample(100:100000, nrow(storeData), replace = TRUE)/100 storeData$transactions <- sample(0:1000, nrow(storeData), replace = TRUE) storeData$traffic <- storeData$transactions + sample(0:1000, nrow(storeData), replace = TRUE) head(storeData) store date dollars transactions traffic 1: A 2012-01-01 48.60 409 990 2: A 2012-01-02 996.89 36 428 3: A 2012-01-03 69.35 647 1103 4: A 2012-01-04 334.56 953 973 5: A 2012-01-05 692.99 958 1753 6: A 2012-01-06 973.32 724 1086 之外的其他结构?

请说明如何组织数据,然后如何使用数据回答示例问题&#34; 2014年1月与2013年1月相比,有多少商店的美元销售增长为正?&#34;和&#34;过去3个月每笔交易的总体趋势是什么?&#34;

3 个答案:

答案 0 :(得分:7)

你在这里问了很多问题。我建议你花时间阅读data.table可以做的涉及连接和聚合数据的所有事情。以下是您如何在第一季度获得每家商店年增长率的示例。

#get the first day of the first month for your binning
minDate<-min(storeData$date); month(minDate)<-1; day(minDate)<-1

#get the first day of the last month for your binning
maxDate<-max(storeData$date); month(maxDate)<-12; day(maxDate)<-1

#Build some bins
yearly<-data.table(leftBound=seq.Date(minDate,maxDate,by="year"))
quarterly<-data.table(leftBound=seq.Date(minDate,maxDate,by="3 months"))
monthly<-data.table(leftBound=seq.Date(minDate,maxDate,by="month"))

#Example for quarterly data
quarterly[, rollDate:=leftBound]
storeData[, rollDate:=date]

setkey(quarterly,"rollDate")
setkey(storeData,"rollDate")

temp<-quarterly[storeData, roll=TRUE] #associate each (store, date) pair with a quarter

#create a "join table" containing each quarter for each store
jt<-CJ(leftBound=quarterly$leftBound, store=unique(storeData$store))
setkey(temp,"leftBound","store")

dt<-temp[jt, allow.cartesian=TRUE]
dt[, `:=`(year=year(leftBound), quarter=quarter(leftBound))]

qSummary<-dt[,list(dollars=sum(dollars, na.rm=TRUE), 
         transactions=sum(transactions, na.rm=TRUE), 
         traffic=sum(traffic, na.rm=TRUE)),
   by=list(year,quarter,store)] #Summarize the data by quarter

#Get year/year growth for Q1
qSummary[,list(dollarGrowth = dollars[which(year==2014 & quarter==1)] / dollars[which(year==2013 & quarter==1)]), by=store]

 #First five rows...
    store dollarGrowth
 1:     A    0.0134860
 2:     B    0.0137215
 3:     C    0.0188249
 4:     D    0.0163887
 5:     E    0.0037576

答案 1 :(得分:2)

您可能需要查看zoo包。这个包使用zoo类,它能够非常好地处理不规则的时间序列。它还有一个zooreg类,类似于ts类,但对于这个答案,我们会坚持使用zoo

这是一个快速解决方案:

Step0:加载包和数据:

# install.packages("zoo")
library(zoo)

storeData <- data.frame()

st.dates <- seq(as.Date('2012-01-01'),as.Date('2014-01-01'),by="day")

n <- length(st.dates)

storeData <- 
  data.frame(
    store = rep(1:26, n),
    dollars = sample(100:100000, n*26, replace = TRUE)/100,
    transactions = sample(0:1000, n*26, replace = TRUE),
    traffic = sample(0:2000, n*26, replace = TRUE)
  )

请注意,我使用的是data.frame而不是data.table,而且数据的构造略有不同。凭借您的专业水平,我相信您可以轻松操控它。

第1步:将数据转换为时间序列

现在,原则上您现在可以将其转换为zoozooreg类:

zoo(storeData, order.by=rep(st.dates,26))

但请注意,每天都会有多个条目对应不同的商店,因此会产生时间序列中多个条目的问题。

因为在我们的案例中,我们每个商店每天都不会有多个条目,所以我们希望将每个商店的信息分开。所以我们按商店分割数据:

storeDataList <- split(storeData,factor(storeData$store))

现在我们已准备好将数据转换为时间序列:

storeDataZooList <- lapply(storeDataList,
                           function(storeData) zoo(storeData, order.by=st.dates))

这给出了所有商店的时间序列数据列表。

第3步:分析

现在您拥有所有商店的时间序列数据,聚合很简单:

您可以按季度或按月汇总任何商店的特定字段:

aggregate(storeDataZooList[[1]]$dollars,as.yearqtr)
aggregate(storeDataZooList[[1]]$dollars,as.yearmon)

您可以按季度或月份汇总任何商店的所有字段:

aggregate(storeDataZooList[[1]],as.yearqtr)
aggregate(storeDataZooList[[1]],as.yearmon)

您可以按季度或月份汇总所有商店的所有字段:

lapply(storeDataZooList,aggregate, as.yearmon)
lapply(storeDataZooList,aggregate, as.yearqtr)

该软件包的文档非常详细,我相信它会对您有很大的帮助。

希望这会有所帮助!!

编辑:请注意,为简单起见,我将storeID保持为数字。如果您有字母数字storeID,则必须在时间序列转换步骤中删除storeID以使聚合工作:

storeDataZooList <- lapply(storeDataList,
                           function(storeData) zoo(storeData[,-1], order.by=st.dates))

答案 2 :(得分:1)

尝试使用包TimeProjection从日期中提取有用的功能并聚合这些派生功能。换句话说,除非您想运行需要data.frame结构的算法,否则请坚持data.tablets