考虑以下形式的数据框
idnum start end
1993.1 17 1993-01-01 1993-12-31
1993.2 17 1993-01-01 1993-12-31
1993.3 17 1993-01-01 1993-12-31
其中start
和end
是Date
类型
$ idnum : int 17 17 17 17 27 27
$ start : Date, format: "1993-01-01" "1993-01-01" "1993-01-01" "1993-01-01" ...
$ end : Date, format: "1993-12-31" "1993-12-31" "1993-12-31" "1993-12-31" ...
我想创建一个 * 新 * Dataframe ,它将针对start
和end
之间的每个月(包括边界)的每一行进行每月观察:
所需输出
idnum month
17 1993-01-01
17 1993-02-01
17 1993-03-01
...
17 1993-11-01
17 1993-12-01
我不确定month
应该是什么格式,我会在某个时候想按idnum
、month
分组,以便对数据集的其余部分进行回归。
到目前为止,对于每一行,seq(from=test[1,'start'], to=test[1, 'end'], by='1 month')
都给了我正确的序列--但一旦我试图将其应用于整个 Dataframe ,它就不起作用了:
> foo <- apply(test, 1, function(x) seq(x['start'], to=x['end'], by='1 month'))
Error in to - from : non-numeric argument to binary operator
6条答案
按热度按时间wgx48brx1#
使用
data.table
:setDT
将df
转换为data.table
。然后,对于每一行by = 1:nrow(df)
,我们根据需要创建idnum
和month
。d7v8vwbk2#
使用
dplyr
:注意,这里我没有为每一行生成一个
start
和end
之间的序列,而是为每一个idnum
生成一个min(start)
和max(end)
之间的序列。omtl5h9j3#
更新2
在
purrr
(0.3.0
)和dplyr
(0.8.0
)的新版本中,可以使用map2
完成此操作更新
根据@阿南达·马赫托的评论
另外,
qyyhg6bp4#
使用
dplyr
和tidyr
为每行创建序列的一个选项可以是:或者使用分组ID创建序列:
或者当目标是每个ID仅创建一个唯一序列时:
nkoocmlb5#
tidyverse
答案数据
回答和输出
zsohkypk6#
还有一种
tidyverse
方法是使用tidyr::expand
: