【问题标题】:Function to define yearly intervals on big data frame in R在 R 中定义大数据帧的年间隔的函数
【发布时间】:2014-04-05 06:08:53
【问题描述】:

我正在研究一个大数据框,以便为提升回归树模型项目准备此数据框。 由于我是 R 和一般编程的新手,所以我被困在数据准备点上。 我已经对这个问题进行了数小时的思考,并且知道我想怎么做。我只是不能在R中做到这一点。 我的数据框基本上是这样的:

start.dateend.date 表示公司(例如C1)一直是我的潜在公司的客户的时间间隔。公司 1 是 2009 年 1 月 1 日至 2009 年 12 月 31 日以及未来两年内的客户。变量amount.x 是支付给我公司客户的金额。

> df <- data.frame(company,start.date,end.date,amount.x)
> df

      company start.date   end.date amount.x
    1      C1 01/01/2009 31/12/2009       10
    2      C1 01/01/2010 31/12/2010       20
    3      C1 01/01/2011 31/12/2011        5
    4      C2 01/01/2009 31/12/2009        7
    5      C2 01/01/2010 31/12/2010       12
    6      C2 01/01/2011 31/12/2011       11

我正在尝试添加一个新列,显示不同公司成为我公司客户的年限。 问题是start.dateend.date 之间的时间间隔并不总是正好是一年。有时公司已成为客户一个月,但这仍应显示为客户 1 年。 它应该是这样的:

> df <- data.frame(company,start.date,end.date,amount.x,Years.as.customer)
> df
      company start.date   end.date amount.x   Years.as.customer
    1      C1 01/01/2009 31/12/2009       10   1
    2      C1 01/01/2010 31/12/2010       20   2 
    3      C1 01/01/2011 31/12/2011        5   3
    4      C2 01/01/2009 31/12/2009        7   1
    5      C2 01/01/2010 31/12/2010       12   2
    6      C2 01/01/2011 31/12/2011       11   3 

我认为这可以通过为每家公司定义一个开始日期来实现。因此,如果出现df$company 中的新名称,请从同一行中的start.date 中获取日期,并将其保留在df$company 中同一公司的所有行中。下一步应该是计算end.dates 和开始日期之间的时间差。如果差值 df$years 中写入 1。 if: 2=> time diff >1 , write year 2 etc.

这应该适用于具有不同日期(两个日期之间并不总是正好 1 年以及不同的开始和结束日期)和大约 3000 家公司的巨大日期框架。

我正在努力定义一个工作函数并将其应用于整个数据框。

我希望我能简要地解释一下这个问题以及我想要解决的问题。如果有任何不清楚的地方,请随时提出问题。我会尽量回答清楚。

谢谢你们的帮助,伙计们。

编辑:重叠年份的问题。 (@休)

为了彻底解决我描述的问题,我正在处理最后一个问题: 我结合使用了 dplyr 和 lubridate 包,使用了 Hugh 的解决方案(参见 cmets)。看看下面代码写的结果

company   start.date  end.date   Years.as.customer
    C20   2010-07-10  2010-09-30  1
    C20   2010-07-10  2011-06-30  2
    C20   2010-07-10  2011-06-30  2
    C20   2010-07-10  2011-06-30  2
    C20   2010-07-10  2011-06-30  2 
    C20   2010-07-10  2011-06-30  2
    C20   2010-10-01  2010-12-31  1
    C20   2011-01-01  2011-03-31  2
    C20   2011-04-01  2011-06-30  2

问题在于,C20 公司成为客户的时间只有一年。如果将第一行作为开始,则所有日期(从 start.date 列中的第一个日期到 end.date 列中的最后一个日期)都在一年内。 我猜当 end.date 列中的年份从 2010 年到 2011 年发生变化时,Years.as.customer 列中的值也会从 1 变为 2。对于所有给定的行,它应该保持为 1,因为时间间隔仍然

提前致谢。

【问题讨论】:

  • 澄清您的要求的几个问题:a) end.datestart.date 之间的差异可以大于一年吗? b) 对于一家在 2012 年成为客户并在 2014 年再次成为客户但不是 2013 年的公司,您希望看到什么?
  • 如果我理解正确:如果每一行只能包含一年内的日期,并且一年内的日期只能在一行上给出,那么您可以尝试with(df, ave(company, company, FUN = seq_along))
  • 使用公司作为索引和长度(唯一(x))作为函数在格式(开始,“%Y”)上运行“聚合”。
  • 感谢您的提问。 @Viktor K.:a)时差不能超过一年。 b) 我不认为有任何类似描述的案例。如果有的话,我认为从第 1 年重新开始会很有价值。

标签: r date datetime dataframe apply


【解决方案1】:

我认为这可以满足您的需求:

library(dplyr)
library(lubridate)

df$start.date <- as.Date(df$start.date, format="%d/%m/%Y")
df$end.date <- as.Date(df$end.date, format="%d/%m/%Y")

  df %.% 
  group_by(company) %.% 
  # mutate(Years.as.customer = year(end.date) - min(year(start.date)) + 1)
  mutate(Years.as.customer = 
           ceiling((end.date - min(start.date))/365.25))


# months
library(zoo)
df %.%
  group_by(company) %.%
  mutate(Months.as.customer = as.yearmon(end.date) - min(as.yearmon(start.date)) + 1)

【讨论】:

  • 感谢您的回复。很抱歉没有早点回来。这接近我正在寻找的东西。感谢您与我分享这些信息。我有两点难以获得最终解决方案。 a) 对于大多数公司来说,这个解决方案非常有效,谢谢。对于一些公司来说,新公司的第一行不是从第一年开始的,而是以某种方式接管了前公司最后一行的价值。知道这可能是什么原因吗? b)有没有办法每月做一次,而不是增加一整年?两年之间有几个时间间隔。谢谢!
  • (a) 我不完全确定您的意思,但如果您的数据不准确,再多的编码也无济于事。你怎么知道一些公司的第一行被上一行接管了(而不仅仅是巧合)? (b) 您是指作为客户的月份吗?如果这回答了您的问题,请查看我的编辑。
  • 查看我的问题的编辑以了解问题 (a)。这是我正在努力解决的最后一点。感谢到目前为止所做的一切。
  • @Hugh:感谢您的编辑。除了 $start.date 和 $end.date 中年份不同的日期之外,使用 difftime() 进行分组工作正常。如果我们以以下两个日期为例,它们是公司 20 的第一个日期: 2006-07-01(开始) 2007-06-30(结束) 这两个日期之间的时间差是
  • 有效!非常感谢,休!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-17
  • 1970-01-01
  • 2015-01-06
相关资源
最近更新 更多