我在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
至少连续2次name
观察。因此,我想删除第4,5和8行。如何在R中做到最好?
修改
感谢下面的评论,我可以更清楚一点。如果我对name
= C
和year
= 2004
进行了额外的观察(第9行),我希望将第8行和第9行与其他行保持在一起。
答案 0 :(得分: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,]
答案 1 :(得分: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
答案 2 :(得分: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,]
})