将日期转化为假人,每月的某天和一年中的某月

时间:2018-07-17 07:21:16

标签: r date lubridate dummy-variable

我有一个类似这样的日期向量:

ds <- lubridate::as_date(c("2015-11-23", "2015-11-24", "2015-11-25", 
     "2015-11-26", "2015-11-27", "2015-11-30", "2015-12-01", "2015-12-02",
                           "2015-12-03", "2015-12-04"))

此向量包含按升序排列的日期,但在某些日期之间缺少。例如,在此示例中,缺少11月28日和11月29日。

我现在想将这些日期变成假人。

一个假人应该只是月份,另一个假人应该指出每个月内的位置。在上面的示例中,2015年11月的第一个观测值是2015年11月23日。

在这种情况下,结果将是:

df <- data.frame(November = c(1, 1, 1, 1, 1, 1, 0 ,0 ,0 ,0),
                 December = c(0, 0, 0, 0, 0, 0, 1 ,1 ,1 ,1),
                 d1 = c(1, 0,0,0,0,0,1,0,0,0),
                 d2 = c(0, 1,0,0,0,0,0,1,0,0),
                 d3 = c(0, 0,1,0,0,0,0,0,1,0),
                 d4 = c(0, 0,0,1,0,0,0,0,0,1),
                 d5 = c(0, 0,0,0,1,0,0,0,0,0),
                 d6 = c(0, 0,0,0,0,1,0,0,0,0)) 

> df
   November December d1 d2 d3 d4 d5 d6
1         1        0  1  0  0  0  0  0
2         1        0  0  1  0  0  0  0
3         1        0  0  0  1  0  0  0
4         1        0  0  0  0  1  0  0
5         1        0  0  0  0  0  1  0
6         1        0  0  0  0  0  0  1
7         0        1  1  0  0  0  0  0
8         0        1  0  1  0  0  0  0
9         0        1  0  0  1  0  0  0
10        0        1  0  0  0  1  0  0

其中d1表示该特定月份的首次观察日期。 请注意,它应该推广到很多年。

我尝试过的是这个

nov <- ds[months(ds) == 'November']

d1 <- ifelse(ds %in% nov & ds == dplyr::first(nov), 1, 0 )

1 个答案:

答案 0 :(得分:1)

如果我理解正确,OP希望为每个月和事件按出现顺序创建虚拟变量。

可以使用dcast()包中的rowid()data.table函数来解决此问题:

ds <- lubridate::as_date(c("2015-11-23", "2015-11-24", "2015-11-25", 
                           "2015-11-26", "2015-11-27", "2015-11-30", "2015-12-01", "2015-12-02",
                           "2015-12-03", "2015-12-04"))

library(data.table)
tmp <- data.table(ds)[, month := format(ds, "%Y-%m")]
dcast(tmp, ds ~ month, length, value.var = "ds")[
  dcast(tmp, ds ~ sprintf("d%02i", rowid(month)), length, value.var = "ds"),
  on = "ds"][, -"ds"]
    2015-11 2015-12 d01 d02 d03 d04 d05 d06
 1:       1       0   1   0   0   0   0   0
 2:       1       0   0   1   0   0   0   0
 3:       1       0   0   0   1   0   0   0
 4:       1       0   0   0   0   1   0   0
 5:       1       0   0   0   0   0   1   0
 6:       1       0   0   0   0   0   0   1
 7:       0       1   1   0   0   0   0   0
 8:       0       1   0   1   0   0   0   0
 9:       0       1   0   0   1   0   0   0
10:       0       1   0   0   0   1   0   0

说明

将日期向量转换为data.table对象,并在其中添加一列,以明确的格式表示年份和月份(ISO 8601)。

然后,dcast()被调用两次:(1)为每个月创建虚拟变量,(2)为事件创建虚拟变量。 rowid(month)按照每月出现的顺序对事件进行计数。如果每月有9个以上的事件,则sprintf()用于用前导0格式化列标题。

dcast()的每次调用都会创建最终解决方案的一部分。通过加入日期将两个部分合并在一起。最后,ds被删除。