[R-es] Error en loop anidado con data.table

Rodrigo López Correa rod99hare en gmail.com
Vie Ene 20 16:09:13 CET 2017


Hola Carlos, primero gracias por contestar.



Disculpas por no haber sido del todo claro. El objetivo es completar las
columnas rankf8, rankf10 y rankf12 según el siguiente criterio:

·         *El valor a asignar a rankf8*, va a depender de la *diferencia
entre el valor de t_8a en “datos” y el valor de t_8a en “mat”*.



·         *El valor a asignar a rankf10*, va a depender de la *diferencia
entre el valor de t_10a en “datos” y el valor de t_10a en “mat”*.



·         *El valor a asignar a rankf12*, va a depender de la *diferencia
entre el valor de t_12a en “datos” y el valor de t_12a en “mat”*.



Los valores a asignar para cada columna rankf  también van a depender del
valor en cada año que debe ser el mismo al comparar los valores en
“datos”como para los valores en “mat”.


Por ejemplo: columna rankf8.



1)      Si t_8a en “datos” *<=* al valor en t_8a en “mat” + 10% del valor
en t_8a en “mat”: asigna 1 a rankf8.



2)      Si t_8ª en “datos” *>* t_8a en “mat” + 10% de t_8a en “mat” y *<=*
t_8a en “mat” + 50% de t_8a en “mat”: asigna 2 a rankf8.





3)      Si t_8ª en “datos” *>* t_8a en “mat” + 50% de t_8a en “mat” y t_8a
en “mat”es diferente de NA: asigna 3 a rankf8.



4)      Si no se cumplen esas condiciones: asigna 4 a rankf8.



Similares criterios debo seguir para asignar valores a rankf10 y rankf12,
pero las referencias son los valores de t_10a en “datos” y “mat” para
rankf10 y los valores de t_12a en “datos” y “mat”.



*Ante tus preguntas:*

·  Entiendo bien que el "1" de rankf8 (en negrita negro) corresponde al 100
de t_8a que está en la primera fila de t_8a de la matriz pequeña

Es correcto.


El valor de t_8a en “datos” para el *año 1*, es 100.


El valor de t_8a en  “mat” para el *año 1*, es 100.


En este caso t_8a en “datos” es <= suma de 100 (t_8a en “mat”) + 100(t_8a
en “mat”) *0.1.


Por tanto asigno a rankf8, 1.



·  ¿Pero el "1" de rankf10 (negrita rojo) ?. La primera fila de t_10a en la
matriz pequeña no es un 220 si no un 200.

               El valor de t_10a en “datos” para el *año 1*, es 220.

               El valor de t_10a en  “mat” para el* año 1, *es 200.

               En este caso t_10a en “datos” es <= suma de 200 (t_10a en
“mat”) + 200(t_10a en “mat”) *0.1.

               Por tanto asigno a rankf10, 1.


·  Y algo parecido para el "1" de rankf12 (negrita azul). Hay que buscar un
220 en t_12a de la matriz pequeña... ¡Y no está en la primera fila!.

              El valor de t_12a en “datos” para el *año 1*, es 220.

              El valor de t_12a en  “mat” para el* año 1, *es 200.

              En este caso t_12a en “datos” es <= suma de 200 (t_12a en
“mat”) + 200(t_12a en “mat”) *0.1.

              Por tanto asigno a rankf12, 1.



Espero haber sido un poco más claro ahora. ¡Muchas gracias!

Rodrigo.





El 20 de enero de 2017, 11:12, Carlos Ortega <cof en qualityexcellence.es>
escribió:

> Hola,
>
> Por entender el problema:
>
> id anio t_8a t_10a t_12a rankf8 rankf10 rankf12
> 1 1 100 220 220 *1* *1 1*
> 2 1 140 350 350 2 3 3
> 3 2 55 165 165 1 1 1
> 4 2 60 200 200 2 2 2
> 5 2 100 NA NA 3 4 4
> 6 3 NA 350 350 NA 2 2
>
>
>    - Entiendo bien que el "1" de rankf8 (en negrita negro) corresponde al
>    100 de t_8a que está en la primera fila de t_8a de la matriz pequeña
>    - ¿Pero el "1" de rankf10 (negrita rojo) ?. La primera fila de t_10a
>    en la matriz pequeña no es un 220 si no un 200.
>    - Y algo parecido para el "1" de rankf12 (negrita azul). Hay que
>    buscar un 220 en t_12a de la matriz pequeña... ¡Y no está en la primera
>    fila!...
>
> -------Matriz Pequeña-----
>   t_8a t_10a t_12a
> 1  100   200   200
> 2   50   150   150
> 3   NA   250   250
>
> Con estas dudas no termino de entender la lógica a aplicar.
>
>
> Gracias,
> Carlos Ortega
> www.qualityexcellence.es
>
>
> El 19 de enero de 2017, 21:29, Rodrigo López Correa <rod99hare en gmail.com>
> escribió:
>
>> Hola tengo una tabla de tipo data.frame "datos" con la siguiente
>> estructura, simplificada en número de niveles por variable, para crear un
>> ejemplo más sencillo:
>>
>> id anio t_8a t_10a t_12a rankf8 rankf10 rankf12
>> 1 1 100 220 220 NA NA NA
>> 2 1 140 350 350 NA NA NA
>> 3 2 55 165 165 NA NA NA
>> 4 2 60 200 200 NA NA NA
>> 5 2 100 NA NA NA NA NA
>> 6 3 NA 350 350 NA NA NA
>>
>> También tengo una matriz, "mat" con la siguiente estructura:
>>
>>   t_8a t_10a t_12a
>> 1  100   200   200
>> 2   50   150   150
>> 3   NA   250   250
>>
>>
>>
>> La columna rankf8 la quiero rellenar tomando como referencia valores de
>> t_8a en "datos" en relación al valor de t_8a en la matriz "mat" y según el
>> año que le corresponda (1, 2 o 3).
>>
>> Del mismo modo quiero rellenar los valores de rankf10 y rankf12 pero
>> tomando como referencia valores de t_10a en "datos" en relación al valor
>> de
>> t_10a en la matriz "mat" y valores de t_12a en "datos" en relación al
>> valor
>> de t_12a en la matriz "mat, y según el año que le corresponda (1, 2 o 3).
>>
>> *Mi objetivo es que quede la tabla "datos" con las columnas rankf8,
>> rankf10
>> y rankf12 completas según la condición del script:*
>>
>> id anio t_8a t_10a t_12a rankf8 rankf10 rankf12
>> 1 1 100 220 220 1 1 1
>> 2 1 140 350 350 2 3 3
>> 3 2 55 165 165 1 1 1
>> 4 2 60 200 200 2 2 2
>> 5 2 100 NA NA 3 4 4
>> 6 3 NA 350 350 NA 2 2
>>
>>
>>
>> *Mi script es el siguiente:*
>>
>>
>> datos<-data.frame(cbind(id,anireg_cod,t_8a,t_10a,t_12a,rankf
>> 8,rankf10,rankf12))
>>
>> datos<-data.table((datos),key="anireg_cod")
>>
>> datos[order(anireg_cod,decreasing=FALSE),]
>>
>> anio<-sort((unique(datos$anireg_cod)))
>>
>> tiempo<-as.character(c("t_8a","t_10a","t_12a"))
>>
>>
>> mat<-matrix(c(100,50,NA,200,150,250,200,150,250),3,3)
>> colnames(mat)<-tiempo
>> rownames(mat)<-seq(1:length(sort(unique(datos$anireg_cod))))
>>
>> anio<-sort((unique(datos$anireg_cod)))
>>
>>
>> rank<-as.character(c("rankf8","rankf10","rankf12"))
>>
>> for (k in 1:nrow(datos)){
>>
>>   #recorre variable anio
>>
>>   for (i in anio){
>>
>>     for(j in tiempo){
>>
>>       for(l in rank){
>>
>>         ifelse(i==datos$anireg_cod & j %in% colnames(datos) &
>> (datos[k,l==colnames(datos)]
>>
>>                <=mat[i==rownames(mat)
>>                ,j==colnames(mat)]*0.1 +
>> mat[i==rownames(mat),j==colnames(mat)]),
>>                datos[k,l %in% colnames(datos)]<-1,
>>
>>                ifelse(i==datos$anireg_cod & j %in% colnames(datos) &
>> (datos[k,l %in% colnames(datos)]>
>>                         mat[i==rownames(mat),j==colnames(mat)]*0.1 +
>>                mat[i==rownames(mat),j==colnames(mat)] &
>> (i==datos$anireg_cod & j %in% colnames(datos) & (datos[k,l %in%
>> colnames(datos)])))<=
>>
>> mat[i==rownames(mat), j==colnames(mat)]*0.5 + mat[i==rownames(mat),
>> j==colnames(mat)],
>>                datos[k,l %in% colnames(datos)]<-2,
>>
>>                 ifelse(i==datos$anireg_cod & j %in% colnames(datos) &
>> (datos[k,l %in% colnames(datos)] & !is.na(datos[k,l %in%
>> colnames(datos)])
>> >
>>
>> mat[i==rownames(mat),j==colnames(mat)]*0.5),
>>                           datos[k,l %in% colnames(datos)] <-3, 4)))
>>                    }
>>     }
>>
>>   }
>>
>>
>> }
>>
>>
>> *El error que se genera es:*
>>
>> Error in `[<-.data.table`(`*tmp*`, k, l %in% colnames(datos), value = 1) :
>>
>>   j must be vector of column name or positions
>>
>>
>>
>> In addition: Warning message:
>>
>> In i == datos$anireg_cod & j %in% colnames(datos) & (datos[k, l ==  :
>>
>>   longer object length is not a multiple of shorter object length
>>
>>
>>
>> Muchas gracias y disculpas si quedó muy largo pero quería explicitar eel
>> problema lo mejor posible.
>>
>>
>>
>> Saludos,
>>
>> Rodrigo.
>>
>>
>>
>>
>> --
>> *Dr. Rodrigo López Correa.*
>>
>> Montevideo.
>> Uruguay.
>> Cel: 099 660 549.
>>
>>         [[alternative HTML version deleted]]
>>
>> _______________________________________________
>> R-help-es mailing list
>> R-help-es en r-project.org
>> https://stat.ethz.ch/mailman/listinfo/r-help-es
>>
>
>
>
> --
> Saludos,
> Carlos Ortega
> www.qualityexcellence.es
>



-- 
*Dr. Rodrigo López Correa.*

Montevideo.
Uruguay.
Cel: 099 660 549.

	[[alternative HTML version deleted]]



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