我有一个类似这样的日期向量:
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 )
答案 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
被删除。