【问题标题】:R loop to calculate date intervalsR循环计算日期间隔
【发布时间】:2015-04-27 14:33:24
【问题描述】:

我有一个如下所示的数据框(客户):

    email    order_no  date       
a@stack.com  0012      2014-02-13  
a@stack.com  0013      2014-03-13  
a@stack.com  0014      2014-06-13  
b@stack.com  0015      2014-05-13   
b@stack.com  0016      2014-05-20  
b@stack.com  0017      2014-07-20   

我想为每个客户创建一个附加订单间隔的新字段。第一步是按日期升序排序:

customer <- arrange(customer, date)

下一步将遍历每个客户并计算订单间隔,因此结果集如下所示:

    email    order_no  date         days_interval
a@stack.com  0012      2014-02-13    0
a@stack.com  0013      2014-03-13    30
a@stack.com  0014      2014-06-13    90
b@stack.com  0015      2014-05-13    0 
b@stack.com  0016      2014-05-20    7
b@stack.com  0017      2014-07-20    60

可以不使用 for 循环来实现吗? 这样做最有效的方法是什么。

使用 FOR 循环,您可以这样做:

for (i in 2:nrow(customer)){
  if(customer$email[i]==customer$email[i-1]){
    customer$interval[i] <- as.integer(difftime(customer$date[i],customer$date[i-1]))
  }
}

不使用 for 循环是否可行?

【问题讨论】:

  • 两个数据框不匹配。例如,订单0016 在顶部数据框中是2014-06-13,在底部是2014-05-20
  • 我的错误。进行更新

标签: r loops for-loop


【解决方案1】:

diff 应该适合你。它接受一个长度为 n 的向量,并返回一个长度为 n-1 的向量,其中包含向量项之间的差异。下面是一个例子。

> data <- data.frame(name=c("jeff","steve","jim"),date=today()+seq(-3:-5))
> data
   name       date
1  jeff 2015-04-28
2 steve 2015-04-29
3   jim 2015-04-30
> diff(data$date)
Time differences in days
[1] 1 1

您只需将其与您当前的工作结合起来。比如用

customer$days_interval <- c(0, diff(customer$date))

【讨论】:

  • 谢谢。但是,这并不能解决我的问题,如果我的问题有点含糊,请原谅我。我想要实现的是 - 对于每封电子邮件,获取最早日期(分钟)和下一个日期(分钟 + 1)的日期差异。如果有另一个订单日期,那么我想计算 (min+1) 和 (min+2) 之间的差异,依此类推。有了这个,我将在每个客户的订单之间有一个真正的间隔。
【解决方案2】:

这就是我要做的,使用dplyrlubridate

library(dplyr)
library(lubridate)

df %>%
  group_by(email) %>%
  mutate(date = ymd(date)) %>%
  arrange(date) %>%
  mutate(days_interval = difftime(date, lag(date), unit="days"))

这是我得到的:

        email order_no       date days_interval
1 a@stack.com       12 2014-02-13       NA days
2 a@stack.com       13 2014-03-13       28 days
3 a@stack.com       14 2014-06-13       92 days
4 b@stack.com       15 2014-05-13       NA days
5 b@stack.com       16 2014-05-20        7 days
6 b@stack.com       17 2014-07-20       61 days

【讨论】:

  • 尝试了您的解决方案,但在进行 QA 时,它没有产生预期的结果。我看到最小日期的间隔不是 N/A 的情况。
  • 谢谢,但还是没有解决。我们将默认设置为最小日期,但是我们不会比较位置 2 到 3 和位置 3 到 4 的日期等等。这就是让我相信 for 循环是唯一可行的方法的原因。
  • 参考日期是该客户的最短订购日期。每个订单日期的参考日期都会发生变化。对于每个客户(电子邮件),我想获取最早日期(分钟)和下一个日期(分钟 + 1)的日期差异。如果有另一个订单日期,那么我想计算 (min+1) 和 (min+2) 之间的差异,依此类推。有了这个,我将为每个客户的订单之间建立一个真正的间隔。
  • 也许只有我一个人,但这并不能解决我的问题。我在上面发布了一个 For Loop 解决方案。或许这样会更清楚。我想知道是否可以在不使用 For 循环的情况下复制它。我之所以这么说是因为它需要大约一个小时才能运行。谢谢。不知道为什么我得到了很多反对票...
猜你喜欢
  • 2019-03-07
  • 1970-01-01
  • 2020-09-26
  • 1970-01-01
  • 2017-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-05
相关资源
最近更新 更多