4

我在 R 中有一个不平衡的面板数据集。以下将作为示例:

dt <- data.frame(name= rep(c("A", "B", "C"), c(3,2,3)), 
                 year=c(2001:2003,2000,2002,2000:2001,2003))

> dt
  name year
1    A 2001
2    A 2002
3    A 2003
4    B 2000
5    B 2002
6    C 2000
7    C 2001
8    C 2003

现在,我需要year对每个name. 因此,我想删除第 4、5 和 8 行。如何在 R 中最好地做到这一点?

编辑: 感谢下面的评论,我可以更清楚一点。name如果我对=Cyear=有额外的观察(第 9 行)2004,我希望将第 8 行和第 9 行与其他行一起保留。

4

3 回答 3

4

我的(hackish)方法是:

is.consecutive = duplicated(rbind(dt,transform(dt, year=year+1), 
                                     transform(dt, year=year-1)),
                            fromLast=TRUE)[1:nrow(dt)]

is.consecutive包含要保留的观测值的布尔向量。对于您的示例,此向量将是:TRUE TRUE TRUE FALSE FALSE TRUE TRUE FALSE

最后,您可以轻松地使用此向量对您的 data.frame 进行子集化,例如:

dt[is.consecutive,]
于 2014-03-02T20:42:07.093 回答
4

这是一个更(太……?)复杂的替代方案,您可以在其中设置连续观察的最小运行长度。

dt <- dt[order(dt$name, dt$year), ]

rl <- 2

do.call(rbind,
        by(dt, dt$name, function(x){
          run <- c(0, cumsum(diff(x$year) > 1))
          x[ave(run, run, FUN = length) >= rl, ]
        })
)
#     name year
# A.1    A 2001
# A.2    A 2002
# A.3    A 2003
# C.6    C 2000
# C.7    C 2001

rl <- 3

do.call(rbind,
        by(dt, dt$name, function(x){
          run <- c(0, cumsum(diff(x$year) > 1))
          x[ave(run, run, FUN = length) >= rl, ]
        })
)
#     name year
# A.1    A 2001
# A.2    A 2002
# A.3    A 2003
于 2014-03-02T23:37:49.060 回答
3

这里使用的解决方案ddply

library(plyr)
ddply(dt,"name",function(x) {
    cons_idx=which(diff(x$year)==1)
    cons_idx=sort(unique(c(cons_idx,cons_idx+1)))
    x[cons_idx,]
})
于 2014-03-03T02:06:24.250 回答