1

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

 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))

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

4

2 回答 2

0

我们可以使用Mapwith stack。通过使用Map,我们得到'start'的每个值到对应'end'的序列,然后将list输出的名称设置为countrycolumn并将其转换list为两data.framestack

res <- stack(setNames(Map(`:`, o$start, o$end), o$country))[2:1]
colnames(res) <- c("country", "year")
all.equal(res, on)
#[1] TRUE

更新

如果还有其他列,那么我们可以通过获取 a listwith来稍微改变方法Map,然后使用 thelengths查找length每个list元素的,使用它复制数据集的行,最后cbindunlistedlist输出为“年份”

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
于 2017-01-25T16:18:26.900 回答
0

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

dplyr::select用于删除表示“开始”和“结束”分组的额外变量。

library(tidyr)

gather(o, time, years, -country) %>%
    dplyr::select(-time) %>%
    dplyr::group_by(country) %>%
    complete(years = full_seq(years, period = 1))
于 2017-01-25T17:30:17.093 回答