Вопрос
Как я могу исправить приведенный ниже код, чтобы он работал достаточно быстро, чтобы обрабатывать запрос на 3,2 миллиона строк, не задыхаясь в разделе вычислений, как сейчас.Быстрое здесь означает максимум часов, но не дней, и я подозреваю, что минуты на ПК, на котором он работает, являются разумными.
Проблема
У меня есть локальная база данных sql, и я пытаюсь выполнить расчет данныхновое значение и запишите его обратно в другую таблицу.Однако в настоящее время код расчета очень медленный.Я обрабатываю приблизительно 3,2 миллиона записей, так что это проблема.Все это работает в visual studio R.
Я никогда раньше не использовал R, поэтому я не уверен, что к чему.На самом деле у меня было много проблем с поиском хорошей документации, чтобы добраться до этой точки.Я подозреваю из-за нехватки скорости и из-за того, что кажется, что она замедляется, что в цикле я либо читаю данные, используя индекс в списке, либо пишу в список, который не использует ссылку на конец.
library(RODBC)
db <- odbcConnect("LocalDB")
results <- sqlQuery(db,'Select * from stockAppData;')
print("Completed loading data!")
results$pDate = as.Date(results$pDate)
results$Symbol = as.character(results$Symbol)
results$Exchange = as.character(results$Exchange)
print("Completed formating data")
#Table to temporarily hold results that will be uploaded to sql db.
table <- data.frame(Symbol = character(),
Exchange = character(),
pDate = as.Date(character()),
pCloseChange = double(),
stringsAsFactors = FALSE)
print("MADE TABLE")
#This is the loop that seems to be super slow
for (i in 2:dim(results[1])) {
s <- results$Symbol[i]
e <- results$Exchange[i]
d <- results$pDate[i]
if (results$Symbol[i] == results$Symbol[i - 1]) {
pcc <- (results$pClose[i] / results$pClose[i - 1]) - 1
table <- rbind(table, c(s,e,d,pcc))
} else {
cat("Calculated Pcgain for: ", results$Symbol[i-1] , "\n" ,sep = "")
}
}
#Never been here because the loop takes forever
cat("Finished Calculations: returning results to DB")
columnTypes <- list(Symbol = "VARCHAR(10)", Exchange = "Varchar(5)", pDate = "date", pCloseChange = "DOUBLE PRECISION")
sqlSave(db,table,varTypes = columnTypes, rownames = FALSE,colnames = FALSE)
odbcClose(db)
Дополнительный фон
Другие вещи, которые я подозреваю, медленные, но не медленные, это сравнение персонажей У меня было много проблем со сравнением факторов, и я не знаю, как это сделать правильно.Мне также не обязательно нужна двойная точность, но я предпочитаю ее, поскольку она потребует дополнительных вычислений.
Логика цикла
Каждый раз, когда цикл запускается, мы оцениваем переменную pcc, которая обозначает «Процент изменения закрытия», который равен закрытию предыдущих дней, деленному на закрытие текущих дней минус 1Цикл просто добавляет эту информацию вместе с символом, обменом и датой из записи в день, который мы оцениваем, в таблицу результатов.Как объяснено в ответе, я использовал RBIND в цикле, что определенно является причиной его медленной работы.
Оператор if гарантирует, что мы пропустим первую запись для данной комбинации обмена символами.Это гарантирует, что мы пропустим первый день любой защиты, так как мы не можем вычислить pcc, так как он полагается на предыдущий день, и текущий символ будет другой защитой.См. Пример ниже * Примечание: ввод и вывод являются упрощенными примерами.
Пример ввода
Symbol Exchange pDate pClose
APP TSX 2018-01-13 1.00
APP TSX 2018-01-14 2.00
APP NYSE 2018-01-13 2.00
APP NYSE 2018-01-14 3.00
APPL TSX 2018-01-13 2.00
APPL TSX 2018-01-14 3.00
Пример вывода
Symbol Exchange pDate pcc
APP TSX 2018-01-14 1.00
APP NYSE 2018-01-14 1.00
APPL TSX 2018-01-14 0.5