Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 时间序列中连续/未中断的事件_R_Datetime - Fatal编程技术网

R 时间序列中连续/未中断的事件

R 时间序列中连续/未中断的事件,r,datetime,R,Datetime,我正在使用R中的一个数据表,其中包含美国杂货店销售的产品的季度信息。特别是,有一列表示日期,一列表示商店,一列表示产品。例如,以下是数据的一个子集(非常小): Date StoreID ProductID 2000-03-31 10001 20001 2000-03-31 10001 20002 2000-03-31 10002 20001 2000-06-30 1000

我正在使用R中的一个数据表,其中包含美国杂货店销售的产品的季度信息。特别是,有一列表示日期,一列表示商店,一列表示产品。例如,以下是数据的一个子集(非常小):

Date           StoreID       ProductID
2000-03-31     10001         20001       
2000-03-31     10001         20002
2000-03-31     10002         20001
2000-06-30     10001         20001
对于每家商店中的每一种产品,我想知道在该日期之前,该产品在该商店中连续销售了多少个季度。例如,如果我们仅限于查看在特定商店销售的订书机,我们将:

Date           StoreID       ProductID
2000-03-31     10001         20001       
2000-06-30     10001         20001
2000-09-30     10001         20001
2000-12-31     10001         20001      
2001-06-30     10001         20001
2001-09-30     10001         20001
2001-12-31     10001         20001
假设这是StoreID和ProductID组合的所有数据,我想将一个新变量指定为:

Date           StoreID       ProductID     V
2000-03-31     10001         20001         1
2000-06-30     10001         20001         2
2000-09-30     10001         20001         3
2000-12-31     10001         20001         4
2001-06-30     10001         20001         1
2001-09-30     10001         20001         2
2001-12-31     10001         20001         3
2002-03-31     10001         20001         4
2002-06-30     10001         20001         5
2002-09-30     10001         20001         6
2002-12-31     10001         20001         7
2004-03-30     10001         20001         1
2004-06-31     10001         20001         2
请注意,我们在2000年第四季度之后进行了延期,因为该产品在2001年第一季度没有销售。此外,由于该产品在2003年第一季度没有销售,我们在2002年第四季度之后进行展期。下一次销售该产品是在2004年第一季度,该季度被分配为1


我面临的问题是,我的实际数据集相当大(大约1000万行),因此需要高效地完成这项工作。我唯一能想到的技术是效率极低的。如果您有任何建议,我们将不胜感激。

您可以使用自定义函数计算季度之间的差异

# Load data.table
library(data.table)
# Set data as a data.table object
setDT(data)
# Set key as it might be big data
setkey(data, StoreID, ProductID)

consecutiveQuarters <- function(date, timeGap = 14) {
    # Calculate difference in dates 
    # And check if this difference is less than 14 weeks
    shifts <- cumsum(c(FALSE, abs(difftime(date[-length(date)], date[-1], units = "weeks")) > timeGap))
    # Generate vector from 1 to number of consecutive quarters
    ave(shifts, shifts, FUN = seq_along)
}

# Calculate consecutive months my storeID and productID
data[, V := consecutiveQuarters(Date), .(StoreID, ProductID)]
#加载数据表
库(数据表)
#将数据设置为data.table对象
setDT(数据)
#设置关键点,因为它可能是大数据
setkey(数据、存储ID、产品ID)

连续季度创建一个变量,如果产品在一个季度内销售,则该变量为1,否则为0。对变量进行排序,使其从当前开始,并在时间上向后移动

将此类变量的累积和与相同长度的序列进行比较。当销售额降至零时,累计总和将不再等于序列。累计总和等于序列的次数,这将表明连续季度的销售额为正

data <- data.frame(
  quarter = c(1, 2, 3, 4, 1, 2, 3, 4),
  store = as.factor(c(1, 1, 1, 1, 1, 1, 1, 1)),
  product = as.factor(c(1, 1, 1, 1, 2, 2, 2, 2)),
  numsold = c(5, 6, 0, 1, 7, 3, 2, 14)
)


sortedData <- data[order(-data$quarter),]

storeValues <- c("1")
productValues <- c("1","2")

dataConsec <- data.frame(store = NULL, product = NULL, ConsecutiveSales = NULL)

for (storeValue in storeValues ){
  for(productValue in productValues){

    prodSoldinQuarter <- 
      as.numeric(sortedData[sortedData$store == storeValue &
                        sortedData$product == productValue,]$numsold > 0)

    dataConsec <- rbind(dataConsec,
                        data.frame(
                          store = storeValue,
                          product = productValue,
                          ConsecutiveSales = 
                            sum(as.numeric(cumsum(prodSoldinQuarter) == 
                                     seq(1,length(prodSoldinQuarter)) 
                                    ))
                          ))

  }
} 

数据我从您的问题中了解到,您真正需要的V列是一年中的季度,而不是每个季度的产品总和。你可以用这样的东西

# to_quarters returns year's quarter of given date in character string
# base on reg exp    
to_quarters <- function(date_string) {
  month <- as.numeric(substr(date_string, 6, 7))
  as.integer((month - 1) / 3) + 1
}

# with tidyverse library
library(tidyverse)
# your data as tibble format of data frame
data_set_tibble <- as.tibble(YOUR_DATA)
# here you create your table 
data_set_tibble %>% mutate(V = to_quarters(Date) %>% as.integer())


# alterative with data.table library
library(data.table)
# your data as data.table format of data frame
data_set  <- as.data.table(YOUR_DATA)
# here you create your table 
data_set[,.(Date, StoreID, ProductID, V = to_quarters(Date))]
#to#季度以字符串形式返回给定日期的年度季度
#基于reg exp

为什么第5行中的V重置为1?是因为时差太大还是因为今年是新年?另外,请使用
dput
功能添加更多数据(多个门店和产品)。由于10001门店有一个季度没有销售产品20001,因此会重置数据。请注意,日期跳过了。我的解决方案有效吗?或者有什么我可以改进的吗?@PoGibas我正在评估它。看起来很有希望!这不是我需要的。我想要一个产品在商店里连续销售的季度数。不是一个季度,所以这不太管用。对于给定的商店,假设相同的产品连续销售10个季度(为简单起见,从给定年份的第一季度开始)。沿着日期看,不是得到1,2,3,4,5,6,…,10,而是这个代码给了我1,2,3,4,1,2,3,4,1,2。之所以会出现这种情况,是因为当一年结束时,季度间的差异为-1。如果我们通过取差模4来改变连续四分之一函数中“移位”的定义,这就解决了问题,但增加了一个新的问题。代码将Q1Y1和Q2Y100视为顺序。我们一定要以某种方式把这一年合并起来吗?想法?@Joe你能给你的问题加上这样的例子吗(连续几年必须返回1:10)。您可以使用函数
dput()
,因为我添加了这样一个示例(但只有1-7而不是1-10)。我还添加了一个新问题的例子,引入模运算会导致这个问题。@Joe我编辑了我的答案。我将其更改为使用函数
difftime
。利用它,我们以周为单位计算差异(最大允许单位),并检查此差异是否工作正常。非常感谢你的帮助!