rollapply для больших данных с использованием sparklyr

Я хочу оценить скользящую ценность риска для набора данных, состоящего примерно из 22,5 миллионов наблюдений, поэтому я хочу использовать sparklyr для быстрых вычислений. Вот что я сделал (используя образец базы данных):

library(PerformanceAnalytics)
library(reshape2)
library(dplyr)

data(managers)
data <- zerofill(managers)
data<-as.data.frame(data)
class(data)
data$date=row.names(data)
lmanagers<-melt(data, id.vars=c('date'))

Теперь я оцениваю VaR с помощью пакетов dplyr и PerformanceAnalytics:

library(zoo) # for rollapply()
var <- lmanagers %>% group_by(variable) %>% arrange(variable,date) %>% 
  mutate(var=rollapply(value, 10,FUN=function(x) VaR(x, p=.95, method="modified",align = "right"), partial=T))

Это прекрасно работает. Теперь я делаю это, чтобы использовать sparklyr:

library(sparklyr)
sc <- spark_connect(master = "local")
lmanagers_sp <- copy_to(sc,lmanagers)
src_tbls(sc)

var_sp <- lmanagers_sp %>% group_by(variable) %>% arrange(variable,date) %>% 
  mutate(var=rollapply(value, 10,FUN=function(x) VaR(x, p=.95, method="modified",align = "right"), partial=T)) %>% 
  collect

Но это дает следующую ошибку:

Error: Unknown input type: pairlist

Кто-нибудь может сказать мне, где ошибка и какой правильный код? Также приветствуется любое другое решение для более быстрой оценки VaR.


person Jairaj Gupta    schedule 03.09.2017    source источник
comment
вы понимаете, что data$date=row.names(data) дает вам вектор character, а не Date? Что произойдет, если вы сделаете data$date <- as.Date(row.names(data))   -  person C8H10N4O2    schedule 07.09.2017


Ответы (2)


Для пользовательских dplyr серверных частей, таких как sparklyr, mutate в настоящее время не поддерживаются произвольные функции R, определенные в других пакетах; поэтому rollapply() в настоящее время не поддерживается.

Чтобы рассчитать стоимость, подверженную риску в sparklyr, одним из подходов является расширить sparklyr с помощью Scala и R и следовать подходу, аналогичному следующему: Оценка финансовых рисков с помощью Apache Spark.

person Javier Luraschi    schedule 05.09.2017

Разобью ваш вопрос на две задачи:

  • как сделать скользящее самосоединение (т. е. a.manager_id = b.manager_id and a.date < b.date and b.date <= a.date + 10) с интерфейсом sparklyr
  • как использовать пользовательскую функцию (например, VaR) с интерфейсом sparklyr

Первая задача может быть возможной с dplyr глаголами, которые поддерживают ограниченный набор Оконные функции, включая lead() и lag(). Вы, вероятно, получите что-то действительно уродливое, вроде (lag(return,1) + lag(return,2) + lag(return,3))/(3 - is.na(lag(return,1)) - is.na(lag(return,2)) - is.na(lag(return,3)) — просто общий пример. (К сожалению, условные соединения, например окна даты, по-прежнему не поддерживаются в dplyr - этот вопрос кажется, часто встречается, например этот.)

Гораздо проще было бы просто написать первую задачу на Direct Spark SQL (с условным самосоединением, описанным выше), обернутым DBI::dbGetQuery().

Вторая задача — статистическая, ее нельзя выполнить просто с помощью dplyr или прямого SQL, и она имеет зависимость от библиотеки, которую sparklyr не поддерживает, поэтому вам нужно использовать Scala (или Python) определяемая пользователем функция (UDF) для расчета VaR, например один уже связан в другой ответ.

tl;dr Первую задачу можно выполнить через sparklyr (но используя SQL, а не dplyr). Для второй задачи требуется внешняя пользовательская функция, которую затем можно invoke() через sparklyr.

person C8H10N4O2    schedule 07.09.2017