2

我有一个数据框,其中包含列名为 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 的最后 2 行

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

3 回答 3

7

您可以按如下方式使用“data.table”包(假设您以data.frame命名为“mydf”的开头):

> 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]
于 2013-03-19T17:54:25.430 回答
4

假设您的数据称为DF

lasttwo <- do.call(rbind,by(DF,DF$FirmID,tail,2))
于 2013-03-19T17:42:15.033 回答
3

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

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. FirmID在:上拆分数据split(dat, dat$FirmID)。这将返回一个列表,我们
  2. lapply结束,应用该tail函数最多返回最后两行,结果是一个列表,其组件是 的结果tail,然后我们
  3. do.call使用和组合回数据框rbind

整个调用可以串成一行:

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
于 2013-03-19T17:44:29.980 回答