首页 > 解决方案 > 使用带有 lapply() 的 R 中的值列表进行过滤太慢了

问题描述

我有一个独特的股票名称列表(大约 12,000 只股票)及其“以前的最大收入”和一个相当大的数据框。数据框包含股票名称、收入、收入年份。例如:

AAPL | 2000 | 1,000
AAPL | 2001 | 1,200
AAPL | 2002 | 900
AMZN | 2000 | 300
AMZN | 2001 | 500
MSFT | 2000 | 600

我需要从大型数据框中检查股票在哪一年超过了其“先前的最大收入”。由于每家公司报告的收入年份不同,有的有 2000-2002 年的数据,有的有更多(2000-2005 年),有的有更少(2000-2001 年)。

我的方法是筛选股票名称。所以,我必须对每只股票都这样做。这就是为什么我使用 lapply() 但它太慢了。

下面是我要说的部分。

rec_year <- function(sym) {
  recovery_year <- (post_table %>% filter(tic==sym & ni > pre_max_table[pre_max_table$tic==sym]$ni))$fyear[1]
  return(recovery_year - pre_max_table[pre_max_table$tic==sym]$fyear)
}
YearsRecover <- unlist(lapply(tic_list,rec_year))

ni:净收入 tic:股票名称 fyear:财政年度

pre_max_table包含股票列表及其之前的最大收入。例如:苹果 | 2001 | 1,200 亚马逊 | 2002 | 900 毫秒 | 2001 | 1000

post_table包含新数据以检查之前的最大值pre_max_table

该函数rec_year()首先检查pre_max_table. 然后它检查股票名称在哪一年sym超过了之前的最大值。如果它找到了一年,它会返回上一个最大收入年份与sym打破自己记录的年份之间的差值。然后,我将其lapply()应用于rec_year()tic_list

我认为代码运行缓慢,因为它必须遍历许多 tic 名称(12k)。每次它都必须重新运行该rec_year()功能。

如果有人能提出更好/更快的方法来解决这个问题,我将不胜感激。

标签: roptimizationapplylapply

解决方案


有没有办法在不使用 lapply() 的情况下做到这一点(为每个组找到一个特定的值)?

这是一种与原始方法相反的方法,首先选择所有收入较高的行,然后从这些行中删除除每只股票的第一行之外的所有行:

# pick all rows from post_table with income higher than that from pre_max_table
ps = subset(post_table, ni > pre_max_table[post_table['tic']]$ni)
# pick only the first row for each stock
pnd = ps[!duplicated(ps$tic), c('tic', 'fyear')]
# compute the "recover" time for each stock (including NAs)
YearsRecover = pnd[levels(pnd$tic), 'fyear'] - pre_max_table$fyear

推荐阅读