获取每个组中的最后2行

时间:2013-03-19 17:32:26

标签: r dataframe

我有一个数据框,其中包含列名为FirmID和DEF的数据行。列DEF仅包含零。 FirmID列包含公司ID。我想对给定的FirmID进行最后2次观察。 DEF列仅为零。

FirmID LTQ DLCQ DEF
1004   0.45 0.21 0 
1004   0.32 0.43 0
1004   0.36 0.47 0
1004   0.25 0.67 0
1004   0.56 0.34 0
1021   0.12 0.39 0
1021   0.16 0.31 0
1021   0.24 0.76 0
1021   0.37 0.56 0
1035   0.89 0.78 0
...      .   .   .
...      .   .   .

那么如何获得给定FirmID的最后两行

1004  .   .   0
1004  .   .   0
1021  .   .   0
1021  .   .   0
1035  .   .   0
1035  .   .   0

3 个答案:

答案 0 :(得分:7)

您可以使用“data.table”包,如下所示(假设您从名为“mydf”的data.frame开始):

> library(data.table)
> DT <- data.table(mydf, key="FirmID")
> DT[, tail(.SD, 2), by = key(DT)]
   FirmID  LTQ DLCQ DEF
1:   1004 0.25 0.67   0
2:   1004 0.56 0.34   0
3:   1021 0.24 0.76   0
4:   1021 0.37 0.56   0
5:   1035 0.89 0.78   0

显然,将“2”更改为您实际想要的行数(问题的标题和文本中存在矛盾)。


另一个选择是以类似的方式使用plyr

> library(plyr)
> ddply(mydf, .(FirmID), tail, 2)
  FirmID  LTQ DLCQ DEF
1   1004 0.25 0.67   0
2   1004 0.56 0.34   0
3   1021 0.24 0.76   0
4   1021 0.37 0.56   0
5   1035 0.89 0.78   0

并且,使用基数R的一个不寻常的替代方案:

temp <- within(mydf, {
  ID <- ave(FirmID, FirmID, FUN = function(x) rev(seq_along(x)))
})

temp[temp$ID %in% c(1, 2), 1:4]

答案 1 :(得分:4)

为您提供数据称为DF

lasttwo <- do.call(rbind,by(DF,DF$FirmID,tail,2))

答案 2 :(得分:3)

执行此操作的base-R方法是手动执行split-apply-combine舞蹈。使用您的数据:

dat <- read.table(text = "FirmID LTQ DLCQ DEF
1004   0.45 0.21 0 
1004   0.32 0.43 0
1004   0.36 0.47 0
1004   0.25 0.67 0
1004   0.56 0.34 0
1021   0.12 0.39 0
1021   0.16 0.31 0
1021   0.24 0.76 0
1021   0.37 0.56 0
1035   0.89 0.78 0", header = TRUE)

我们

  1. 将数据拆分为FirmIDsplit(dat, dat$FirmID)。这将返回我们
  2. 的列表
  3. lapply结束,应用tail函数最多返回最后两行,结果是一个列表,其组件是tail的结果,然后我们< / LI>
  4. 使用do.callrbind
  5. 组合回数据框

    整个电话可以串成一行:

    do.call("rbind", lapply(split(dat, dat$FirmID), tail, 2))
    

    给出:

    > (out <- do.call("rbind", lapply(split(dat, dat$FirmID), tail, 2)))
           FirmID  LTQ DLCQ DEF
    1004.4   1004 0.25 0.67   0
    1004.5   1004 0.56 0.34   0
    1021.8   1021 0.24 0.76   0
    1021.9   1021 0.37 0.56   0
    1035     1035 0.89 0.78   0
    

    如果您不喜欢那些讨厌的行名称,只需删除它们:

    > rownames(out) <- NULL
    > out
      FirmID  LTQ DLCQ DEF
    1   1004 0.25 0.67   0
    2   1004 0.56 0.34   0
    3   1021 0.24 0.76   0
    4   1021 0.37 0.56   0
    5   1035 0.89 0.78   0