我在R中有一个data.frame/data.table,如下所示:

df <- data.frame(
  ID = c(rep("A", 20)),
  year = c(1968, 1971, 1972, 1973, 1974, 1976, 1978, 1980, 1982, 1984, 1985,
           1986, 1987, 1988, 1990, 1991, 1992, 1993, 1994, 1995)
)

我想对df进行子集化,以仅保留那些具有至少连续五年的条目。在此示例中,这是两个时期(1984:1988和1990:1995)的情况。我如何在R中做到这一点?

最佳答案

使用diffcumsum的紧凑型解决方案:

setDT(df)[, grp := cumsum(c(0, diff(year)) > 1), by = ID
          ][, if (.N > 4) .SD, by = .(ID, grp)][, grp := NULL][]

这给出了预期的结果:
    ID year
 1:  A 1984
 2:  A 1985
 3:  A 1986
 4:  A 1987
 5:  A 1988
 6:  A 1990
 7:  A 1991
 8:  A 1992
 9:  A 1993
10:  A 1994
11:  A 1995

解释:
  • 使用grp := cumsum(c(0, diff(year)) > 1), by = ID,您可以为每个ID连续创建一个(临时)分组变量。
  • 使用if (.N > 4) .SD, by = .(ID, grp),您只能为每个ID选择具有连续5年或更多年的组。
  • 使用grp := NULL删除(临时)分组变量。


  • 基于R的可比较方法:
    i <- with(df, ave(year, ID, FUN = function(x) {
      r <- rle(cumsum(c(0, diff(year)) > 1));
      rep(r$lengths, r$lengths)
      } ))
    
    df[i > 4,] # or df[which(i > 4),]
    

    这将为您带来相同的结果。

    关于r - 在data.frame中按连续年份分割,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40831682/

    10-11 22:20
    查看更多