根据两列年份的差异重塑数据

Reshape data based on difference of the two columns years

我想根据两列重塑数据,即开始年份和结束年份,就像面板数据一样。通过重塑,我可以基于两个唯一的 id 列进行融合,但这有点棘手。我想根据差异纵向扩展它并添加一个名为 change 的列(表示第一年为 1,否则为 0)。有什么建议吗?

这是 df 的格式。

A <- c("xyz", "xyz", "x","x","x", "y")
start <- c("2001", "1999", "2001", "2000", "1998", "2001")
end <- c("2002", "2001", "2002", "2001", "2000", "2001")
df<- data.frame(A, start,end)

我要最终数据如下

  A     year   change
 xyz    2001     1
 xyz    2002     0
 xyz    1999     1
 xyz    2000     0
 x      2001     1
 x      2002     0
 x      2000     1
 x      2001     0
 x      1998     1
 x      1999     0
 x      2000     0
 y      2001     1

这可以使用包 "reshape2":

library(reshape2)
df <- melt(df, id = "A")

我们现在有一个 ID 列,一个指示观测值是来自 "start" 年还是 "end" 年的变量列,以及一个给出每个 [=] 对应年份的值列19=] 和 "end" 与每个 ID 关联。

您描述的"change"变量在功能上等同于熔化原始数据框产生的变量列。我们可以通过将值 1 分配给 "start" 观察值并将值 0 分配给 "end" 观察值来更明确地复制它。

df$change <- 0
df$change[df$variable == "start"] <- 1

怎么样:

### OP's code
A <- c("xyz", "xyz", "x","x","x", "y")
start <- c("2001", "1999", "2001", "2000", "1998", "2001")
end <- c("2002", "2001", "2002", "2001", "2000", "2001")
df<- data.frame(A, start,end)

### cast the variables start and end to integer in df
start<-as.integer(start)
end  <-as.integer(end)
df   <-data.frame(A, start, end, stringsAsFactors=F)

### Build up the required columns
expand_year<-with(df, mapply(seq,start,end))
expand_A <- rep(df$A,sapply(expand_year,length))
change<-sapply(expand_year,function(x){ c(1,rep(0,length(x)-1)) })

### Put all the columns into a data.frame
final<-data.frame(A=expand_A,
              year=unlist(expand_year),
              change=unlist(change))

输出:

> final
     A year change
1  xyz 2001      1
2  xyz 2002      0
3  xyz 1999      1
4  xyz 2000      0
5  xyz 2001      0
6    x 2001      1
7    x 2002      0
8    x 2000      1
9    x 2001      0
10   x 1998      1
11   x 1999      0
12   x 2000      0
13   y 2001      1