Carlos Santos
2021-Sep-25 12:10 UTC
[R-es] problema de tiempo de ejecución con una rutina dentro de un programa de R
Un millón de gracias Carlos, lo pruebo hoy sin falta, estaba precisamente dando vueltas y mas vueltas con todo esto, porque me tiene un poco angustiado. En cuanto lo pruebe te escribo sin falta y te comento. gracias de nuevo y un abrazo Carlos El sáb, 25 sept 2021 a las 13:35, Carlos Ortega (<cof en qualityexcellence.es>) escribió:> Hola, > > Lo siguiente como punto de partida creo que te puede ayudar. > > Hace lo que has comentado, aunque en el proceso me he encontrado con > algunas dudas que he incluido en el codigo. > He usado data.table (y su variante tidytable en modo dplyr) y stringi que > dan ese punto de velocidad.. > > > #----------------------- > > #---- Library loading > suppressPackageStartupMessages({ > library(dplyr) > library(magrittr) > library(data.table) > library(tidytable) > library(stringi) > }) > > #----- Data Loading > Lines <- "V0 V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 > 1 63 1 1 145 A 233 1 2 3 0 > 2 67 1 4 160 A 286 0 2 2 3 > 3 67 2 4 120 B 229 0 2 2 2 > 4 37 1 3 130 C 250 0 0 3 0 > 5 41 1 2 130 C 204 0 2 1 0 > 6 56 2 2 120 A 236 0 0 1 0 > 7 62 1 4 140 B 268 0 2 3 2 > 8 57 2 4 120 C 354 0 0 1 0 > 9 63 2 4 130 A 254 0 2 2 1 > 10 53 1 4 140 B 203 1 2 3 0 > 11 57 2 4 140 B 192 0 0 2 0 > 12 56 1 2 140 A 294 0 2 2 0 > 13 56 2 3 130 C 256 1 2 2 1 > 14 44 2 2 120 B 263 0 0 1 0 > 15 52 2 3 172 B 199 1 0 1 0" > > #----- Get initial data.frame > midt <- as.data.table(read.table(textConnection(Lines), header = TRUE, > as.is = TRUE)) > > #----- Get all pairs combinations > pairs_val <- unique(midt$V5) > comb_tmp <- as.data.frame(combn(pairs_val, 2)) > > #---- References > ref_val <- c(0.34, 0.66) > > #----- Function for distances > fun_dis <- function(x) { > dis_tmp <- sqrt((x[1] - ref_val[1])^2 + (x[2] - ref_val[2])^2) > return(dis_tmp) > } > > > #----- Function to calculate percentages by V2. > fun_compa <- function(comb_tmp, dt_one) { > for (i in 1:ncol(comb_tmp)) { > val_one <- comb_tmp[1,i] > val_two <- comb_tmp[2,i] > > dt_one <- midt[ V5 == val_one | V5 == val_two, ] > #--- Duda: Aquí no sé si hay que sumar todas las columnas salvo la de > las letras y la del grupo. > res_val <- dt_one[ , .(res_sum = sum(V1,V3,V4,V6,V7,V9,V9,V10)) , by > = V2] > res_val %<>% > mutate.(res_tot = sum(res_sum)) %>% > mutate.(res_per = res_sum/res_tot) %>% > select.(res_per) > dt_comp <- cbind(dt_comp, res_val) > } > return(dt_comp) > } > > #------ Process > dt_comp <- data.table() > for (i in 1:ncol(comb_tmp)) { > #--- Solo proceso las dos primeras combinaciones. No sé cómo hacer con > las siguientes ya que desaparece "A". > res_tmp <- fun_compa(comb_tmp[,1:2], dt_one) > to_sust <- comb_tmp[, which.max(apply(res_tmp, 2, fun_dis))] > midt[ , V5 := stri_replace_all_fixed(V5, to_sust[1], to_sust[2])] > } > > midt > #------- > > Gracias, > Carlos Ortega > www.qualityexcellence.es > > El jue, 23 sept 2021 a las 20:08, Carlos Santos (< > carlossantos.csm en gmail.com>) escribió: > >> Exacto, eso es Carlos >> >> El jue., 23 sept. 2021 20:04, Carlos Ortega <cof en qualityexcellence.es> >> escribió: >> >>> OK. Gracias. >>> >>> Sí, bueno lo del nombre de V5 o el que sea efectivamente da igual, ¿pero >>> es siempre una única columna por la que hay que agrupar?. >>> Y luego en esa columna ¿se ha de iterar hasta que quede solo una letra? >>> (letra o el factor que sea). >>> >>> Gracias! >>> Carlos. >>> >>> El jue, 23 sept 2021 a las 20:00, Carlos Santos (< >>> carlossantos.csm en gmail.com>) escribió: >>> >>>> Gracias Carlos, lo has entendido perfectamente >>>> >>>> El punto definido que he puesto, no siempre tendrá esos mismos valores, >>>> >>>> La columna V5 no siempre tendrá los mismos valores, pero puede valerme >>>> que siempre tenga el mismo nombre de columna, por si eso puede ayudar, ya >>>> que se puede cambiar el nombre de columna antes de llegar a esa rutina si >>>> fuese necesario para que la rutina funcione mejor >>>> >>>> >>>> >>>> El jue., 23 sept. 2021 19:49, Carlos Ortega <cof en qualityexcellence.es> >>>> escribió: >>>> >>>>> Gracias Carlos! >>>>> >>>>> Que no dije nada.... :-). >>>>> Creo que ya lo entiendo pero no he podido meterme con ello.. >>>>> A ver si mañana o este fin de semana encuentro un hueco para ver qué >>>>> se me ocurre. >>>>> >>>>> Un par de dudas adicionales que me surgieron al ver el detalle de tu >>>>> respuesta: >>>>> >>>>> - ¿Para el cálculo se usa siempre esa columna "V5" que es la que >>>>> tiene las letras?. >>>>> - Y claro el objetivo al final es que queda solo una letra tras >>>>> entrar a comparar todas las parejas posibles,¿es así?. >>>>> - Y eso de la distancia a ese punto definido... >>>>> - El punto definido ¿es siempre que has indicado? (0.34, 0.66)?. >>>>> >>>>> >>>>> Así, de primeras lo que veo es porqué hacen falta dos bucles o un >>>>> bucle y un while. >>>>> Parece más un proceso recursivo: comienzas con todos los pare de >>>>> parejas, reduces y vuelves a aplicar el proceso de comparación con las que >>>>> quedan. >>>>> Por eso lo de aclarar la duda del primer punto anterior. >>>>> >>>>> Gracias, >>>>> Carlos. >>>>> >>>>> El mié, 22 sept 2021 a las 18:38, Carlos Santos (< >>>>> carlossantos.csm en gmail.com>) escribió: >>>>> >>>>>> Perdón he puesto 2000 columnas pero quería decir 2000 filas >>>>>> >>>>>> El mié., 22 sept. 2021 18:34, Carlos Santos < >>>>>> carlossantos.csm en gmail.com> escribió: >>>>>> >>>>>>> ok Carlos, pongo un ejemplo con pocos registros a ver si puedo >>>>>>> explicarlo mejor: >>>>>>> >>>>>>> Datos: >>>>>>> V0 V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 >>>>>>> 1 63 1 1 145 A 233 1 2 3 0 >>>>>>> 2 67 1 4 160 A 286 0 2 2 3 >>>>>>> 3 67 2 4 120 B 229 0 2 2 2 >>>>>>> 4 37 1 3 130 C 250 0 0 3 0 >>>>>>> 5 41 1 2 130 C 204 0 2 1 0 >>>>>>> 6 56 2 2 120 A 236 0 0 1 0 >>>>>>> 7 62 1 4 140 B 268 0 2 3 2 >>>>>>> 8 57 2 4 120 C 354 0 0 1 0 >>>>>>> 9 63 2 4 130 A 254 0 2 2 1 >>>>>>> 10 53 1 4 140 B 203 1 2 3 0 >>>>>>> 11 57 2 4 140 B 192 0 0 2 0 >>>>>>> 12 56 1 2 140 A 294 0 2 2 0 >>>>>>> 13 56 2 3 130 C 256 1 2 2 1 >>>>>>> 14 44 2 2 120 B 263 0 0 1 0 >>>>>>> 15 52 2 3 172 B 199 1 0 1 0 >>>>>>> >>>>>>> tengo la matriz que sale de V5: >>>>>>> A >>>>>>> B >>>>>>> C >>>>>>> >>>>>>> junto las filas de A con B, y obtengo el punto respecto de V2, y me >>>>>>> da (0.33, 0.67), puesto que V2 tiene dos valores, es un porcentaje en >>>>>>> definitiva >>>>>>> junto las filas de A con C, y se obtiene el punto (0.5, 0.5) >>>>>>> obtengo la distancia euclidea de dichos puntos sobre el punto >>>>>>> definido, supongamos (0.34, 066), lo que significa que la menor distancia >>>>>>> se obtiene entre A y B, por lo tanto las filas que tienen A en V5 se cambia >>>>>>> su valor a C, y se obtiene la siguiente matriz, donde V5 ya no tiene la A >>>>>>> V0 V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 >>>>>>> 1 63 1 1 145 C 233 1 2 3 0 >>>>>>> 2 67 1 4 160 C 286 0 2 2 3 >>>>>>> 3 67 2 4 120 B 229 0 2 2 2 >>>>>>> 4 37 1 3 130 C 250 0 0 3 0 >>>>>>> 5 41 1 2 130 C 204 0 2 1 0 >>>>>>> 6 56 2 2 120 C 236 0 0 1 0 >>>>>>> 7 62 1 4 140 B 268 0 2 3 2 >>>>>>> 8 57 2 4 120 C 354 0 0 1 0 >>>>>>> 9 63 2 4 130 C 254 0 2 2 >>>>>>> >>>>>> > > -- > Saludos, > Carlos Ortega > www.qualityexcellence.es >[[alternative HTML version deleted]]