将"\u date"列转换为Date
类(如果它不在Date
类中),然后使用map2
(或在rowwise
之后也可以执行)获取"start\u date"、"end\u date"之间的seq
,unnest
list
列,并使用pivot_wider
将其reshape 为"wide"格式,从而创建"date"列
library(dplyr)
library(lubridate)
library(purrr)
library(tidyr)
df1 %>%
mutate(across(ends_with('_date'), ymd)) %>%
transmute(date = map2(start_date, end_date, seq, by = "1 day"),
name, value) %>%
unnest(date) %>%
pivot_wider(names_from = name, values_from = value)
-输出
# A tibble: 7 × 3
date x y
<date> <int> <int>
1 2020-01-01 2 NA
2 2020-01-02 2 NA
3 2020-01-03 2 NA
4 2020-01-04 2 NA
5 2020-01-05 2 4
6 2020-01-06 2 4
7 2020-01-07 NA 4
正如OP提到的base R
种方法一样,一个选项是使用Map
在"\u date"列之间创建序列,即创建数据.帧在list
和merge
之间,帧为Reduce
Reduce(function(...) merge(..., all = TRUE),
do.call(Map, c(f = function(u, v, nm, val) {
dat <- 数据.frame(date = seq(as.Date(u), as.Date(v),
by = "1 day"), val)
names(dat)[2] <- nm; dat
}, unname(df1))))
-输出
date x y
1 2020-01-01 2 NA
2 2020-01-02 2 NA
3 2020-01-03 2 NA
4 2020-01-04 2 NA
5 2020-01-05 2 4
6 2020-01-06 2 4
7 2020-01-07 NA 4
数据
df1 <- structure(list(start_date = c("2020-01-01", "2020-01-05"),
end_date = c("2020-01-06",
"2020-01-07"), name = c("x", "y"), value = c(2L, 4L)),
class = "数据.frame", row.names = c("1",
"2"))