Q- 按条件(两个时间段)传播数据集并填充一个新列(两个时间段之间的时间)

Q- spread dataset by condition (two period of time) and fill a new column (time between both periods)

我有一个如下所示的数据集:

 o<- data.frame(country = c("US", "Mexico"), start = c(1972, 1982), end= c(1975, 1986)) 

我想根据年数展开数据集,并重塑数据集,所以最后我可以得到这样的东西:

a<- seq(1972, 1975, 1)
b<- seq(1982, 1986, 1)
on<-data.frame(country = c(rep("US", 4),rep("Mexico", 5)), year = c(a,b))

我不知道如何继续获得代码中描述的预期结果。 预先感谢您的帮助

我们可以使用 Mapstack。通过使用 Map,我们得到 'start' 的每个值到对应的 'end' 的序列,然后将 list 输出的名称设置为 country 列和使用 stack

list 转换为两列 data.frame
res <- stack(setNames(Map(`:`, o$start, o$end), o$country))[2:1]
colnames(res) <- c("country", "year")
all.equal(res, on)
#[1] TRUE

更新

如果还有其他列,那么我们可以通过使用 Map 获得 list 来稍微改变方法,然后使用 lengths 找到 length 每个 list 元素,使用它复制数据集的行,最后 cbind unlisted list 输出为 'year'

o <- data.frame(id = 1:2, country = c("US", "Mexico"), 
           start = c(1972, 1982), end= c(1975, 1986)) 
lst <- Map(`:`, o$start, o$end)
res1 <- cbind(o[rep(seq_len(nrow(o)), lengths(lst)), 1:2], year = unlist(lst))
row.names(res1) <- NULL

使用 tidyr 函数,您可以先 gather 将该数据集转换为长格式,然后在按国家/地区分组的数据集上使用 complete 来填充每个国家/地区的年份。

dplyr::select用于去除代表"start"和"end"分组的额外变量。

library(tidyr)

gather(o, time, years, -country) %>%
    dplyr::select(-time) %>%
    dplyr::group_by(country) %>%
    complete(years = full_seq(years, period = 1))