[R-es] problema de tiempo de ejecución con una rutina dentro de un programa de R

Carlos Santos c@r|o@@@nto@@c@m @end|ng |rom gm@||@com
Sab Sep 25 14:10:52 CEST 2021


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 using 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 using gmail.com>) escribió:
>
>> Exacto, eso es Carlos
>>
>> El jue., 23 sept. 2021 20:04, Carlos Ortega <cof using 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 using 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 using 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 using 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 using 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]]



Más información sobre la lista de distribución R-help-es