【问题标题】:Subsetting a unbalanced panel dataset to have at least 2 consecutive observations in R对不平衡的面板数据集进行子集化以在 R 中至少有 2 个连续的观察值
【发布时间】:2014-04-03 16:03:40
【问题描述】:

我在 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

现在,我需要对每个 name 至少有 2 个连续的 year 观察。因此,我想删除第 4、5 和 8 行。如何在 R 中最好地做到这一点?

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

【问题讨论】:

  • 如果第 9 行包含 C 2004 怎么办?然后你想保留它和第 8 行吗?
  • 如果你有这个名字怎么办:2000,2002,2003,2005,2007,2008?你应该保留2002,2003,2007,2008吗?如果是这样,那将导致不连续的年份。对吗?
  • @JuliánUrbano 是的,我想保留 2002,2003,2007,2008。抱歉,我的问题不清楚,但我不知道如何更好地表达。
  • 我试图想出一种结合plyr::ddply(对name值进行分块操作)和rle()(仅选择连续行)的方法,但还没有任何工作。

标签: r subset panel-data


【解决方案1】:

我的(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,]

【讨论】:

  • 感谢您的回答!它需要排序后的名称,年份,对吗?
  • 一点也不:两个变量都可以沿行随机化:)
  • 这里的解决方案似乎没有使用有关 name 的信息,当您有类似(id year 1 A 2000 2 A 2002 3 B 2003)这样的数据时,这可能会导致问题,第 2 年和第 3 年会是上述解决方案中的TRUE,但它们一开始就不是来自同一个单位。关于如何解决这个问题的任何想法?
  • @JasonGoal 试试你的例子,它工作得很好......关于名称的信息通过时移变换保存:transform(dt, year=year+1)transform(dt, year=year-1)
【解决方案2】:

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

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

【讨论】:

    【解决方案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,]
    })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-22
      • 2012-08-24
      相关资源
      最近更新 更多