У меня возникли проблемы с моим кодом. Прежде всего, я думаю, что это двойной код, так как одна представляет собой набор функций, которые используются для основного кода, который является вложенным в цикл, что-то вроде этого:
hijos <- function(con, clasification, element){
example <- sprintf("(select hcodniv2 from (select pcodniv1, hcodniv1, pcodniv2, hcodniv2, level from stock.clasificaciones where pcodniv1=%d and hcodniv1=pcodniv1 start with pcodniv2=%d connect by prior hcodniv2=pcodniv2)) minus (select pcodniv2 from (select pcodniv1, hcodniv1, pcodniv2, hcodniv2, level from stock.clasificaciones where pcodniv1=%d and hcodniv1=pcodniv1 start with pcodniv2=%d connect by prior hcodniv2=pcodniv2))", clasification, element, clasification, element)
codhijos <- dbSendQuery(con, example)
hijos_df <- fetch(codhijos, n=-1)
if (length(hijos_df$HCODNIV2) == 0) {
hijos_df <- data.frame("HCODNIV2" = element)
}
dbClearResult(codhijos)
hijos_df
}
hijos_string <- function(con, clasification, element) {
df1 <- hijos(con, clasification, element)
df1 <- paste(df1$HCODNIV2,collapse=",")
df1
}
resultado <- function(datos_inversion, classProduct, classBranch, year, product, branch, df1, df2) {
year_1 = year - 1
df5 <- sqldf(sprintf("select * from datos_inversion where CODUNIDAD = 76 and CODNIV1 = 9 and CODNIV2 = %d and CODNIV4 = %d and ANYO = %d and CODNIV3 in (%s) and CODNIV5 in (%s)",classProduct, classBranch, year_1, df1, df2))
df4 <- sqldf(sprintf("select * from datos_inversion where CODUNIDAD = 54 and CODNIV1 = 9 and CODNIV2 = %d and CODNIV4 = %d and ANYO = %d and CODNIV3 in (%s) and CODNIV5 in (%s)",classProduct, classBranch, year_1, df1, df2))
df3 <- sqldf(sprintf("select * from datos_inversion where CODUNIDAD = 54 and CODNIV1 = 9 and CODNIV2 = %d and CODNIV4 = %d and ANYO = %d and CODNIV3 in (%s) and CODNIV5 in (%s)",classProduct, classBranch, year, df1, df2))
df2 <- sqldf(sprintf("select * from datos_inversion where CODUNIDAD = 76 and CODNIV1 = 9 and CODNIV2 = %d and CODNIV4 = %d and ANYO = %d and CODNIV3 in (%s) and CODNIV5 in (%s)",classProduct, classBranch, year, df1, df2))
df7 <- sqldf(sprintf("select * from datos_inversion where CODUNIDAD = 54 and CODNIV1 = 9 and CODNIV2 = %d and CODNIV4 = %d and ANYO = %d and CODNIV3 = %d and CODNIV5= %d",classProduct, classBranch, year, product, branch))
df6 <- sqldf(sprintf("select * from datos_inversion where CODUNIDAD = 54 and CODNIV1 = 9 and CODNIV2 = %d and CODNIV4 = %d and ANYO = %d and CODNIV3 = %d and CODNIV5= %d",classProduct, classBranch, year_1, product, branch))
colnames(df5)[1] <- 'VALOR_IR14'
colnames(df4)[1] <- 'VALOR_IN14'
colnames(df3)[1] <- 'VALOR_IN15'
colnames(df2)[1] <- 'VALOR_IR15'
colnames(df6)[1] <- 'VALOR_IN14_tot'
colnames(df7)[1] <- 'VALOR_IN15_tot'
colnames(df5)[3] <- 'CODUNIDAD_IR'
colnames(df2)[3] <- 'CODUNIDAD_IR'
colnames(df3)[3] <- 'CODUNIDAD_IN'
colnames(df4)[3] <- 'CODUNIDAD_IN'
df6 <- cbind(df6, df7[!names(df7) %in% names(df6)])
df5 <- cbind(df5, df2[!names(df2) %in% names(df5)])
df4 <- cbind(df4, df3[!names(df3) %in% names(df4)])
newdf <- cbind(df5, df4[!names(df4) %in% names(df5)])
newdf$RES1p = log(newdf$VALOR_IR14)
newdf$RES1p_15 = log(newdf$VALOR_IR15)
newdf$Res1p_tot = newdf$RES1p_15 - newdf$RES1p
newdf$Res2p = newdf$VALOR_IN14/ df6$VALOR_IN14
newdf$Res2p_15 = newdf$VALOR_IN15/ df6$VALOR_IN15
newdf$Res2p_tot = (newdf$Res2p + newdf$Res2p_15)/ 2
newdf$RESULTADO = newdf$Res1p_tot * newdf$Res2p_tot
df_resultados = sum(newdf$RESULTADO, na.rm = TRUE)
data_frame <- data.frame("ANYO" = year, "RESULTADO" = df_resultados, "PRODUCTO" = product, "RAMA" = branch, "CLASE_PR" = classProduct, "CLASE_R" = classBranch)
data_frame
}
Эти функции только производят вычисления из данных из фрейма данных из Oracle.
Сам код этот:
x = 1965:2015
d = 2000
g = 1000
y = c(2026,2017,2019,2023)
z = c(1034,1002,1056,1057)
start <- proc.time() # Start clock
dat <- data.frame()
for (year in x) {
for (classProduct in d){
for (product in y) {
prod_string <- hijos_string(con, classProduct, product)
product_df <- c(product, prod_string)
product_df <- paste(product_df, collapse = ",")
for (classBranch in g){
for (branch in z) {
branch_string <- hijos_string(con, classBranch, branch)
branch_df <- c(branch, branch_string)
branch_df <- paste(branch_df, collapse = ",")
consulta <- sprintf("select * from stock.V_CALCULOS where CODNIV1 = 9 and CODNIV2 = %d and CODNIV4 = %d and CODNIV3 in (%s) and CODNIV5 in (%s) order by codniv1, codniv2, codniv3, codniv4, codniv5, codlugar, codunidad, anyo",classProduct, classBranch, product_df, branch_df)
resuni <- dbSendQuery(con, consulta)
datos_inversion <- fetch(resuni, n=-1)
dbClearResult(resuni)
df<-resultado(datos_inversion, classProduct, classBranch, year, product, branch, prod_string, branch_string)
dat <- rbind(dat, df)
}
}
}
}
}
print(dat)
time_elapsed_parallel <- proc.time() - start # End clock
time_elapsed_parallel
dbDisconnect(con)
- Итак, моя проблема в том, что мне нужно каким-то образом распараллелить этот код для работы с несколькими ядрами одновременно. Между тем пакеты pbdR, multicore y и т. Д. Недоступны для используемой версии RStudio (3.4.4).
- Я думаю оптимизировать цикл for для более эффективного использования параллельного кода, но понятия не имею, как это сделать.
Итак, наконец, мой вопрос:
Любые идеи, как оптимизировать цикл for и после того, как распараллелить его, в плане (может быть), как разделить его или что делать, чтобы он выполнялся с 4 ядрами одновременно и экономил время, потому что это займет вечно выполнить, и мне нужно как можно меньше (начальный фрейм данных имеет более 250 000 строк)?
Я использую виртуальную машину Windows с 4 ядрами
Спасибо за помощь, заранее!
PS. точно добавить результат в виде строк в конечном кадре данных