Фильтрация с использованием списка значений в R с помощью lapply () выполняется слишком медленно - PullRequest
0 голосов
/ 01 октября 2019

У меня есть список уникальных названий акций (около 12 тыс. Акций) с их «предыдущим максимальным доходом» и довольно большим фреймом данных. Фрейм данных имеет названия акций, доход, год этого дохода. Например:

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: fiscalгод

pre_max_table содержит список акций вместе с их предыдущим максимальным доходом. Например: AAPL |2001 |1200 AMZN |2002 |900 MSFT |2001 |1000

post_table содержит новые данные для сравнения с предыдущим максимумом в pre_max_table

Функция rec_year() сначала проверяет предыдущий максимальный чистый доход в pre_max_table. Затем он проверяет, в каком году название акции sym побило свой предыдущий максимум. Если он нашел год, он возвращает разницу между годом предыдущего максимального дохода и годом, когда sym побил свой собственный рекорд. Затем я использую lapply(), чтобы применить это rec_year() к списку акций в tic_list

Я думаю, что код работает медленно, потому что он должен повторяться во многих именах тиков (12k). Каждый раз, когда приходится снова запускать эту rec_year() функцию.

Буду признателен, если кто-нибудь сможет предложить лучший / более быстрый способ решения этой проблемы.

Ответы [ 2 ]

0 голосов
/ 07 октября 2019

есть ли способ сделать это (найти определенное значение для каждой группы) без использования 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
0 голосов
/ 02 октября 2019

Поскольку pre_max_table представляется data.table, в качестве первого шага я бы setkey(pre_max_table, tic), так что

  recovery_year <- (post_table %>% filter(tic==sym & ni > pre_max_table[pre_max_table$tic==sym]$ni))$fyear[1]

можно изменить на

  recovery_year <- (post_table %>% filter(tic==sym & ni > pre_max_table[sym]$ni))$fyear[1]

Затем я замечаю, что использование filter() замедляет код , поэтому я перехожу к

  recovery_year <- post_table[post_table$tic==sym & post_table$ni > pre_max_table[sym]$ni, "fyear"][1]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...