r - 在 R 中使用 data.table 进行顺序过滤

标签 r data.table

我的数据如下:

PERMNO date DLSTCD
    10 1983     NA 
    10 1985    250 
    10 1986     NA
    10 1986     NA 
    10 1987    240 
    10 1987     NA  
    11 1984     NA  
    11 1984     NA  
    11 1985     NA  
    11 1987     NA 
    12 1984    240 

我需要根据以下条件过滤行:

  1. 对于每个 PERMNO,按 date
  2. 对数据进行排序
  3. 在公司被除名后解析已排序的数据并删除行(即 DLSTCD != NA)
  4. 如果第一行对应于被除名的公司,则不要包含该公司的任何行

基于这些标准,以下是我的预期输出:

PERMNO date DLSTCD
    10 1983     NA 
    10 1985    250 
    11 1984     NA  
    11 1984     NA  
    11 1985     NA  
    11 1987     NA 

我在 R 中使用 data.table 来处理这些数据。上面的例子是我的实际数据的一个过度简化的版本,它包含大约 300 万行对应于 30k 个PERMNO。

我为此实现了三种不同的方法,如下所示:
r-fiddle: http://www.r-fiddle.org/#/fiddle?id=4GapqSbX&version=3

下面我使用 50k 行的小数据集比较了我的实现。这是我的结果:

时间比较

system.time(dt <- filterbydelistingcode(dt))   # 39.962 seconds
system.time(dt <- filterbydelistcoderowindices(dt))   # 39.014 seconds
system.time(dt <- filterbydelistcodeinline(dt))   # 114.3 seconds

如您所见,我的所有实现都非常低效。有人可以帮我实现一个更快的版本吗?谢谢你。

编辑:这是我用于时间比较的 50k 行示例数据集的链接:https://ufile.io/q9d8u

另外,这里有一个自定义的数据读取函数:

readdata = function(filename){
    data = read.csv(filename,header=TRUE, colClasses = c(date = "Date"))
    PRCABS = abs(data$PRC)
    mcap = PRCABS * data$SHROUT
    hpr = data$RET
    HPR = as.numeric(levels(hpr))[hpr]
    HPR[HPR==""] = NA
    data = cbind(data,PRCABS,mcap, HPR)
    return(data)
}

data <- readdata('fewdata.csv')
dt <- as.data.table(data)

最佳答案

这是 data.table 中的一个尝试:

dat[
  dat[order(date),
  {
    pos <- match(TRUE, !is.na(DLSTCD));
    (.I <= .I[pos] & pos != 1) | (is.na(pos)) 
  },
  by=PERMNO]
$V1]

#   PERMNO date DLSTCD
#1:     10 1983     NA
#2:     10 1985    250
#3:     11 1984     NA
#4:     11 1984     NA
#5:     11 1985     NA
#6:     11 1987     NA

在 250 万行、400000 行和下架日期上对其进行测试:

set.seed(1)
dat <- data.frame(PERMNO=sample(1:22000,2.5e6,replace=TRUE), date=1:2.5e6)
dat$DLSTCD <- NA
dat$DLSTCD[sample(1:2.5e6, 400000)] <- 1
setDT(dat)

system.time({
dat[
  dat[order(date),
  {
    pos <- match(TRUE, !is.na(DLSTCD));
    (.I <= .I[pos] & pos != 1) | (is.na(pos)) 
  },
  by=PERMNO]
$V1]
})
#   user  system elapsed 
#   0.74    0.00    0.76 

不到一秒 - 还不错。

关于r - 在 R 中使用 data.table 进行顺序过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44378743/

相关文章:

r - 如何将 xtabs() 的结果转换为 R 中的数据框?

r - 很难使用 ggplot2 在图像上排列点

r - 转换时保留变量

r - 如何在我自己的包中使用 data.table::setDTthreads() ?

r - 在对某些值进行操作时通过重叠的时间段进行连接

r - 如何合并 dplyr R 中两个不同列的行数据?

r - fwrite.data.table 和 `yyyy-mm-dd hh:mm:ss` 格式优化,具有固定的 UTC 偏移量

r - data.frame 中的错误,未使用的参数

r - 以 R 格式导出 JSON 数据框

R 如何按条件连接data.table?