viernes, 31 de mayo de 2024

Tutorial. Grafos en la cocina (II)

Grafos sabrosos

Continuo con el análisis de redes de ingredientes y platos de la cocina venezolana. En este post exploro los platos con mayor nivel de inermediación. Es decir,con ingredientes que están presentes en diferentes comunidades de platos y constituyen, por decirlo así, ingredientes que le confieren su particularidad a la culinaria venezolana. Posteriormente analizo las comunidades de platos que se conforman en función de los ingredientes que los componen.


Segunda parte. Intermediación y comunidades


Analizo primero cuál es el plato con mayor nivel de intermediación y, luego, las posibles comunidades de acuerdo con los ingredientes. usaré nuevamente todos los platos, pero para facilitar la visualización, me quedaré con los nodos con un grado de intermediación mayor a la mediana:

par(bg="gray98",mar=c(1,1,1,1)) 
# visualizo
plot(todosb)

De acuerdo con la frecuencia de los ingredientes que componen los diversos platos que he tomado para el presente tutorial, los platos de la cocina venezolana se relacionan de la siguiente manera:

Fig.1 - Ingredientes según nivel de intermediación

Nota:Posiblemente no es ninguna sorpresa: los platos con mayor grado de intermediación son aquellos que fungen como acompañantes/segundos platos/postres o platos especiales. Algo que el algorritmo logra capturar, pues no se le ha impuesto a la data ningún tipo de clasificación previa.

Visualizo las comunidades en los nodos con un grado mayor a la mediana:

comunidades<- cluster_louvain(todos1)
      modularity(comunidades)

##      
## [1] 0.05465422


 #pido la particion para generar comunidades 
todos_comunidades<- membership(comunidades)
      


par(bg="gray98",mar=c(1,1,1,1))
 #visualizo 
plot(comunidades, todos1)
      

Fig.2 - Platos según comunidades

Nota:detectan tres comunidades. La sobreposición de los bloques nos confirman lo que señalabamos inicialmente: los 93 platos se elaboran a partir de un grupo reducido de ingredientes.

si visualizamos los platos que comparten menos ingredientes, veremos que, de existir, esta sobreposición no será tan acentuada:


par(bg="gray98",mar=c(1,1,1,1))
 #visualizo 
comunidades2<- cluster_louvain(todos2)
plot(comunidades2, todos2)
     

Fig.3 - Platos según comunidades

Nota:En estos platos hay dos comunidades. El algorritmo logra diferenciar entre postres o comidades que incorporan sabor dulce/huevos, y lo que serían platos que llevan menos dulce y más sal. De allí que el plátano dulce, por ejemplo, pertezca a una comunidad diferente a la del platano sancochado.

Observando las comunidades pero sin los bloques:

Fig.4 - Comunidades

Nota:Las comunidades parecen agruparse, grosso modo, en torno a platos elaborados con harinas/granos/cochino; carnes(blancas, rojas) y sopas/sancochos/cremas. Esta agrupación la visualizaremos mejor cuando observemos los ingredientes.

Tutorial. Grafos en la cocina (I)

Grafos sabrosos

En este trabajo se propone una metodología para analizar la cocina venezolana a través de redes de ingredientes. La metodología se basa en la construcción de grafos a partir de las recetas de platos típicos, utilizando como nodos los ingredientes y como aristas las relaciones de co-ocurrencia entre ellos. Se pretende identificar patrones de uso de ingredientes, relaciones de complementariedad y grupos de platos con características similares.

Metodología

  1. Recolección de datos:
    • Se utilizarán como fuente de datos las recetas de platos venezolanos publicadas en la obra "Cocinar a la venezolana" (El Nacional, 2001).
    • Se extraerá la información sobre los ingredientes de cada plato, incluyendo su tipo (por ejemplo, carne, vegetal, cereal) y, en la medida de lo posible, su variedad específica (por ejemplo, queso blanco duro, queso blanco semi-duro, queso blanco blando).

    La información obtenida es limitada a la fuente utilizada, por consiguiente, el análisis podría variar con otras fuentes.

  2. Construcción de redes. Se crearán dos tipos de redes:
    • Red de platos: Los nodos serán los platos y las aristas representarán la co-ocurrencia de ingredientes entre ellos. El peso de la arista se asociará a la frecuencia de co-ocurrencia.
    • Red de ingredientes: Los nodos serán los ingredientes y las aristas representarán la co-ocurrencia en los mismos platos. El peso de la arista se asociará a la frecuencia de co-ocurrencia.
  3. Análisis de redes.
    • Se aplicarán métricas de redes para caracterizar la estructura y conectividad de las redes.
      • Red de platos: Se analizará el grado de centralidad de los platos, identificando aquellos que son más importantes en la red por su conexión con otros platos. También se pueden identificar comunidades de platos con características similares.
      • Red de ingredientes: Se analizará la centralidad de los ingredientes, identificando aquellos que son más utilizados en la cocina venezolana. También se pueden identificar grupos de ingredientes que se utilizan frecuentemente juntos.
    • Se utilizarán técnicas de visualización para representar las redes y facilitar su interpretación.

Distribuiré este análisis en tres o cuatro posts. Este el el primero. Es importante dejar claro quen o poseo los derechos de autor del material consultado. Este análisis tiene fines educativos.


Primera parte. Grafo de los platos e ingredientes de la cocina venezolana


De acuerdo con la frecuencia de los ingredientes que componen los diversos platos que he tomado para el presente tutorial, los platos de la cocina venezolana se relacionan de la siguiente manera:

par(bg="gray98",mar=c(1,1,1,1)) 
# visualizo
plot(d$g2)
Fig.1 - Relación entre los platos de acuerdo con los ingredientes empleados.

Esta primera imagen nos sugiere que hay una diversidad de platos elaborados a partir de un mismo grupo de ingredientes.Verifico inspeccionando los algunos indicadores:

estructura(e$g2
)
##      Indicadores   valor
## 1          nodos   93.00
## 2        aristas 3310.00
## 3       densidad    0.77
## 4       diametro    4.00
## 5   long.med.cam    1.23
## 6    grado medio   71.18
## 7    modularidad    0.03
## 8 coefic.cluster    0.88


Hay 93 platos y 3325 aristas. Es un grafo casi completo, en el que de un plato, y sus ingredientes, podemos pasar a otros (es decir, con pequeña variación en los ingredientes y a partir del "plato A" podemos obtener el "plato B"). De allí que sea fácil agrupar estos platos en conglomerados (clusters), tal como nos sugiere el coeficiente de cluster.

Todo lo anterior podría ser, por un lado, una gran fortaleza. La cocina venezolana sería la muestra de una gran creatividad. Con pocos ingredientes se logra elaborar una variedad de platos y sazones. Sin embargo, esto podría ser también una debilidad. La escasez de los ingredientes básicos durante un lapso prolongando sometería a prueba la identidad nacional. Significaría un reto a la fuerza de la costumbre, que no contaría, al menos en el corto plazo, con la capacidad para sustituir esos ingredientes y obtener el sabor acostumbrado. El sabor de casa.

Quiero observar este gráfico tomando la mediana de los vinculos como referencia:

 	
 		# me quedo con nodos con grado mayor a la mediana
 	

todos1 <- delete.vertices(e$g2, V(e$g2)[degree(e$g2) < median(degree(e$g2))])

# selecciono solo los nodos con grado menor o igual a la mediana

todos2 <- delete.vertices(e$g2, V(e$g2)[degree(e$g2) >= median(degree(e$g2))])

Visualizamos estos dos subgrafos

 
 # me quedo con nodos con grado mayor a la mediana
 par(bg="gray15",mar=c(1,1,1,1))
plot(todos1)
                      
  
Fig.2 - Platos con grado mayor o igual a la mediana.

Nota:Los platos que comparten un mayor número de ingredientes son, efectivamente, platos que podrían considerarse de consumo diarios o, en algunos casos, de platos especiales (fines de semana/ festividades). Nótese que el mondongo comparte ingredientes particularmente con la ensalada de gallina, fondo de aves, hervido de res, carne mechada, corbullón de mero, pargo relleno, bollos pelones, pollo al horno y arepas. Si faltan ingredientes relacionados con el mondongo, significa que tampoco se podría elaborar, parcial o totalmente, ninguno de esos otros plato

Fig.3 - Platos con grado menor a la mediana.

Nota: El segundo grupo de platos se relaciona, generalmente, con acompañantes (entradas/segundos platos/postres) así como aderezos o platos muy específicos, especialmente de algunas regiones. Paradójicamente, estos platos sí podrían dejarse de lado sin mucha dificultad, pero son los menos centrales en la cocina venezolana, de acuerdo con la fuente que he consultado.

La escasez de sólo un grupo de ingredientes, entonces, parece generar un efecto cascada en la ausencia de platos acostumbrados en la mesa del venezolano. Un pequeño grupo de ingredientes pareciera impedir la posibilidad de que se elaboren varios platos.

Limpieza de datos

Análisis de datos para la planificación estratégica. Grafos. Preprocesamiento de datos

La data que usamos para generar grafos, y para cualquier tipo de análisis, debe estar bien formada. De lo contrario obtendremos un grafo de poca utilidad. Es necesario insistir permanentemente en este punto.He elaborado otros tutoriales relacionados con la limpieza de la data. No basta con tener claridad sobre el tipo de relaciones sobre los que deseamos observar patrones emergentes. Necesitamos que los nodos estén claramente identificados, sin ambigüedades. Daré algunos ejemplos sobre preparar data para generar grafos.

¿Cómo sabemos si nuestros datos se pueden considerar limpios?

Sabemos que nuestros datos están limpios si:

  1. Cada variable forma una columna. O lo que es igual, cada columna contiene información sobre Una sola variable
  2. Cada observación forma una fila
  3. Una tabla/marco de datos para cada tipo de variable
  4. Los nombres de las variables deben ser legibles "importaciones" en lugar de "M" o "im".

Estas reglas sencillas nos ayudarán a que nuestros análisis estén libre de "basura" y, por tanto, no pierdan validez. A continuación ofrezco algunos ejemplos que he seguido para limpiar data en el contexto de análisis grafos. Huelga decir que pueden usarse para limpiar cualquier tipo de data, si presentan la misma Problemática. Los procedimientos que he seguido no son exclusivos, ni necesariamente los más elegantes. Son las soluciones que se me ocurrieron frente al problema que me planteó un marco de datos específicos, en un momento dado. Aun yo misma puedo seguir otra aproximación en otro momento.

Pre-procesamientos. Tres casos

Caso 1. Nombres de variables

Estos casos tienen que ver con, por ejemplo,

  1. Nombres muy largos de variables,
  2. Nombres que pueden no ser informativos si no se cuenta con un libro de códigos (v.g indepa; ps45)
  3. Variables acentuadas o con caracteres no reconocibles por todos los paquetes de R

Delitos por parroquia, Distrito Capital

Tengo un marco de datos con información sobre los delitos ocurridos en distintas parroquias caraqueñas en el año 2003.

names(delitos_parroquiass)
##  [1] "Parroquia"                    "casos.globales"              
##  [3] "poblacion"                    "km2"                         
##  [5] "Homicidio"                    "Lesiones.personales"         
##  [7] "C.Viol..a.la.mujer.y.familia" "Otros.contra.la.persona"     
##  [9] "Hurto"                        "Hurto.auto..........."       
## [11] "Robo"                         "Robo.auto"                   
## [13] "Estafa"                       "Violación"                   
## [15] "Desvalijo.vehiculo"

Procedo de la siguiente forma:

# recorto nombres mas largos
names(delitos_parroquiass)[c(2, 6:8,10,15)]
## [1] "casos.globales"               "Lesiones.personales"         
## [3] "C.Viol..a.la.mujer.y.familia" "Otros.contra.la.persona"     
## [5] "Hurto.auto..........."        "Desvalijo.vehiculo"
names(delitos_parroquiass)[c(2, 6:8,10,15)] <-
        c("total", "lesiones", "violacion",
          "contra.pers", "hurto.auto", "desval.veh")
# llevo todo a minuscula
names(delitos_parroquiass)<-tolower(names(delitos_parroquiass))
names(delitos_parroquiass)
##  [1] "parroquia"   "total"       "poblacion"   "km2"         "homicidio"  
##  [6] "lesiones"    "violacion"   "contra.pers" "hurto"       "hurto.auto" 
## [11] "robo"        "robo.auto"   "estafa"      "violación"   "desval.veh"
# elimino lao acentuada
names(delitos_parroquiass)[14]<-gsub("ó", "o",                                     names(delitos_parroquiass)[14])
names(delitos_parroquiass)
##  [1] "parroquia"   "total"       "poblacion"   "km2"         "homicidio"  
##  [6] "lesiones"    "violacion"   "contra.pers" "hurto"       "hurto.auto" 
## [11] "robo"        "robo.auto"   "estafa"      "violacion"   "desval.veh"

Observese que selecciono sólo los nombres que me interesan, porque hay algunas variables cuyos nombre considero que están bien.

Caballos ganadores del Clásico Internacional del Caribe

Tengo un marco de dato sobre los caballos ganadores del Clásico del Caribe entre 1966 y 2012. En una de las variables está letra “ñ”

names(caballos)
## [1] "N."      "Año"     "Sede"    "Ganador" "Jinete"  "X"
# llevo los nombres a minuscula
names(caballos)<-tolower(names(caballos))

# elimino letra "ñ" y la vocal acentuada

names(caballos)[2]<-gsub("ñ", "ni", names(caballos)[2])

Caso 2. Celdas

En estos casos el problema están en las celdas, es decir, en las categorías/valor de las variables, porque, por ejemplo:

  1. Hay errores ortográficos o una misma categoría se ha transcrito en formas distintas
  2. El contenido no se entiende si no se posee el libro de códigos (las categorías son número, por ejemplo: 1, 2, 3)
  3. Hay la categoría de dos variables en una misma celda
  4. Acentos diacríticos o cualquier caracter que no todos los paquetes de R procesan correctamente

Caballos ganadores del Clásico Internacional del Caribe

Tengo un marco de dato sobre los caballos ganadores del Clásico del Caribe entre 1966 y 2012

head(caballos)
##    n. anio                     sede               ganador
## 1   I 1966     Puerto Rico San Juan  Venezuela Victoreado
## 2  II 1967        Venezuela Caracas    México El Comanche
## 3 III 1968     Puerto Rico San Juan   Puerto Rico Wiso G.
## 4  IV 1969  México Ciudad de México       México Guadamur
## 5   V 1970            Panamá Panamá         México Hashin
## 6  VI 1971        Venezuela Caracas     México Nacozareño
##                         jinete                                x
## 1      Venezuela Gustavo Ávila clasico internacional del caribe
## 2       México Rubén Contreras clasico internacional del caribe
## 3     Puerto Rico Carlos López clasico internacional del caribe
## 4        México Alberto Zepeda clasico internacional del caribe
## 5          México Miguel Yánez clasico internacional del caribe
## 6  Venezuela Guillermo Gavidia clasico internacional del caribe

En las columnas 3:5, que corresponde a las variables “Sede”, “Ganador”, “Jinete” hay dos variables por columna. En el primer caso, se ofrece el país y la ciudad del evento; en el segundo, el país del caballo ganador y el nombre del caballo; y en el último caso, el país del jinete ganador así como el nombre del jinete. Es necesario separar esas variables para que haya seis columnas en lugar de tres. Adicionalmente, puedo eliminar algunas variables que no me serían útiles para crear algún grafo

Separar el pais-sede y la ciudad-sede

Observo que los países sedes casualmene tienen largos diferentes. Eso me permitiría separar los países-sedes de la ciudad-sede tomando como referencia el largo de los caracteres. Para esto usaré la función ncha(), que cuenta el largo de caracteres, luego verifico el número máximo de caracteres presentes en cada celda, para proceder a la extracción. Para ello uso la función by(). Finalmente, con la función ifelse() y basándome en la información anterior, extraigo los nombres de los países sede del evento:

# elimino la columna x
caballos <-caballos[, -6]
# una posibilidad: saber el largo de cada caso
# para luego extraer la informacion 
# creo una nueva variable para almacenar el largo 
# de caracteres en cada celda
caballos$sede.car <-nchar(as.character(caballos$sede))

# verifico usando by
by(caballos$sede.car, caballos$sede, max)
## caballos$sede:  la República Dominicana Santo Domingo
## [1] 38
## -------------------------------------------------------- 
## caballos$sede:  México Ciudad de México
## [1] 24
## -------------------------------------------------------- 
## caballos$sede:  México Tijuana
## [1] 15
## -------------------------------------------------------- 
## caballos$sede:  Panamá Panamá
## [1] 14
## -------------------------------------------------------- 
## caballos$sede:  Puerto Rico Canóvanas
## [1] 22
## -------------------------------------------------------- 
## caballos$sede:  Puerto Rico San Juan
## [1] 21
## -------------------------------------------------------- 
## caballos$sede:  Venezuela Caracas
## [1] 18
## -------------------------------------------------------- 
## caballos$sede:  Venezuela Maracaibo
## [1] 20
## -------------------------------------------------------- 
## caballos$sede: Flag of Trinidad and Tobago.svg Arima
## [1] 37
# creo la variable sede.pais. Si la variable sede.car es
# igual a un numero específico, colocar el nombre, en caso 
# contrario que no coloque ndada
caballos$sede.pais <-ifelse(caballos$sede.car == 38,
                            "rep.dominicana", "")

# aqui cambio un poco, ya que existe informacion en mi nueva 
# variable.  Entonces, si el valor de sede.car es igual a tanto
# colocar el nombre del pais, y si no es igual, colocar la
# informacion que ya esta
caballos$sede.pais <-ifelse(caballos$sede.car == 24, 
                            "mexico", caballos$sede.pais)

caballos$sede.pais <-ifelse(caballos$sede.car == 15, 
                            "mexico", caballos$sede.pais)

# los paises con dos sedes, empleo '|' que significa 'o'
caballos$sede.pais <-ifelse(caballos$sede.car == 18 | caballos$sede.car == 20, 
                            "venezuela", caballos$sede.pais)

caballos$sede.pais <-ifelse(caballos$sede.car == 21 | caballos$sede.car == 22, "puerto rico", caballos$sede.pais)

caballos$sede.pais <-ifelse(caballos$sede.car == 14, "panama", caballos$sede.pais)

caballos$sede.pais <-ifelse(caballos$sede.car == 37, "trinidad.tobago", caballos$sede.pais)

Creo la variable sede-ciudad. El procedimiento anterior e aplicable también a este caso

# creo la variable sede.ciudad
caballos$sede.ciudad <-ifelse(caballos$sede.car == 21,
                              "san.juan", "")
caballos$sede.ciudad <-ifelse(caballos$sede.car == 24,
                              "cdad.mexico",
                              caballos$sede.ciudad)

caballos$sede.ciudad <-ifelse(caballos$sede.car == 15, 
                              "tijuana", caballos$sede.ciudad)

caballos$sede.ciudad <-ifelse(caballos$sede.car == 18,
                              "caracas", caballos$sede.ciudad)
caballos$sede.ciudad <-ifelse(caballos$sede.car == 20,
                              "maracaibo", caballos$sede.ciudad)

caballos$sede.ciudad <-ifelse(caballos$sede.car == 37, 
                              "arima", caballos$sede.ciudad)

caballos$sede.ciudad <-ifelse(caballos$sede.car == 14,
                              "panama", caballos$sede.ciudad)
caballos$sede.ciudad <-ifelse(caballos$sede.car == 22,
                              "canovanas", caballos$sede.ciudad)
caballos$sede.ciudad <-ifelse(caballos$sede.car == 38,
                              "sto.domingo",
                              caballos$sede.ciudad)

Elimino la columna sede.car, que ya cumplió su función

caballos <-caballos[, -6]
names(caballos)
## [1] "n."          "anio"        "sede"        "ganador"     "jinete"     
## [6] "sede.pais"   "sede.ciudad"

Separar pais del caballo ganador, del nombre del caballo

Ahora, arreglo la columna “Ganador”. En algunos casos usaré el paquete “stringr”. Voy a crear un vector separado del marco de datos para facilitar la comprensión del ejemplo:

require(stringr)
#extraigo la columna
ganador <-unlist(as.character(caballos$ganador))

#elimino el espacio inicial
ganador<-str_trim(ganador, "left")

Separo los nombres de acuerdo con el espacio entre ellos. Generalmente este procedimiento podría completarse usando la expresión **strsplit(ganador, " “)**; sin embargo en este caso no funciona bien:

# ejemplifico aplicando  la funcion a los 12 primeros casos
strsplit(ganador, " ")[1:12]
## [[1]]
## [1] "Venezuela Victoreado"
## 
## [[2]]
## [1] "México El" "Comanche" 
## 
## [[3]]
## [1] "Puerto"    "Rico Wiso" "G."       
## 
## [[4]]
## [1] "México Guadamur"
## 
## [[5]]
## [1] "México Hashin"
## 
## [[6]]
## [1] "México Nacozareño"
## 
## [[7]]
## [1] "Panamá Montecarlo"
## 
## [[8]]
## [1] "Panamá Barremina"
## 
## [[9]]
## [1] "México Teziutlán"
## 
## [[10]]
## [1] "México Voy" "Por"        "Uno"       
## 
## [[11]]
## [1] "Venezuela Huracán" "Sí"               
## 
## [[12]]
## [1] "México Ezgarta"

Debo buscar otra alternativa

# ejemplifico aplicando el corte por el espaciado \\s
strsplit(ganador, "\\s")[1:12]
## [[1]]
## [1] "Venezuela"  "Victoreado"
## 
## [[2]]
## [1] "México"   "El"       "Comanche"
## 
## [[3]]
## [1] "Puerto" "Rico"   "Wiso"   "G."    
## 
## [[4]]
## [1] "México"   "Guadamur"
## 
## [[5]]
## [1] "México" "Hashin"
## 
## [[6]]
## [1] "México"     "Nacozareño"
## 
## [[7]]
## [1] "Panamá"     "Montecarlo"
## 
## [[8]]
## [1] "Panamá"    "Barremina"
## 
## [[9]]
## [1] "México"    "Teziutlán"
## 
## [[10]]
## [1] "México" "Voy"    "Por"    "Uno"   
## 
## [[11]]
## [1] "Venezuela" "Huracán"   "Sí"       
## 
## [[12]]
## [1] "México"  "Ezgarta"

Este código funciona mejor, si bien tendremos que solucionar por separado dos o tres casos. Necesito quedarme ahora con la primera parte de la información:

sapply(strsplit(ganador, split="\\s"), "[[", 1)[1:12]
##  [1] "Venezuela" "México"    "Puerto"    "México"    "México"   
##  [6] "México"    "Panamá"    "Panamá"    "México"    "México"   
## [11] "Venezuela" "México"

Puedo crear entonces la nueva variable denominada pais.ganador, por ejemplo, y corregir los nombres que no quedaron completos

#creo la nueva variable, llevandola a minuscula
pais.ganador <-tolower(sapply(strsplit(ganador, 
                                       split="\\s"), "[[", 1))

# corrijo, puerto rico, y republica dominicana
# busco y reemplazo la palabra que comienza y termina con 'la'
pais.ganador <-gsub("^la$", "rep.dominicana", pais.ganador)
# busco y reemplazo la palabra que empieza y termina 
#con 'puerto'
pais.ganador <-gsub("^puerto$", "puerto.rico", pais.ganador)

El siguiente paso consiste en obtener el nombre de los caballos ganadores. Tendremos que dar algunos pasos adicionales para obtener el nombre completo

caballos.gan<-sapply(strsplit(ganador, split="\\s"), "[[", 2)

#cambio los caballos por posicion, por ejemplo
caballos.gan[2]
## [1] "El"
caballos.gan[2]<-"el comanche"
# en bloque, obtendre un mensaje de advertencia. NO pasa nada
caballos.gan[c(3,10,14,15,16,20, 21:24, 26,27, 
           33, 35, 38:41, 43,45)] <-c("Wiso G",
                                      "Voy Por Uno",
                                      "El Cómico",
                                      "Guaybanex",
                                      "Verset Dancer",
                                      "Rayo Laser",
                                      "Don Gabriel",
                                      "Vuelve Candy B",
                                      "Verset's Jet",
                                      "EL Gran Nano",
                                      "My Own Business",
                                      "Gran Abuelo",
                                      "Borrascoso",
                                      "Ay Papá",
                                      "Soy Conquistador",
                                      "Sicótico",
                                      "Water Jet",
                                      "El de Chine")
## Warning in caballos.gan[c(3, 10, 14, 15, 16, 20, 21:24, 26, 27, 33, 35, :
## number of items to replace is not a multiple of replacement length
caballos.gan<- tolower(caballos.gan)

Agrego las dos variables al marco de datos

caballos<-data.frame(caballos, pais.ganador, caballos.gan)
head(caballos)
##    n. anio                     sede               ganador
## 1   I 1966     Puerto Rico San Juan  Venezuela Victoreado
## 2  II 1967        Venezuela Caracas    México El Comanche
## 3 III 1968     Puerto Rico San Juan   Puerto Rico Wiso G.
## 4  IV 1969  México Ciudad de México       México Guadamur
## 5   V 1970            Panamá Panamá         México Hashin
## 6  VI 1971        Venezuela Caracas     México Nacozareño
##                         jinete   sede.pais sede.ciudad pais.ganador
## 1      Venezuela Gustavo Ávila puerto rico    san.juan    venezuela
## 2       México Rubén Contreras   venezuela     caracas       méxico
## 3     Puerto Rico Carlos López puerto rico    san.juan  puerto.rico
## 4        México Alberto Zepeda      mexico cdad.mexico       méxico
## 5          México Miguel Yánez      panama      panama       méxico
## 6  Venezuela Guillermo Gavidia   venezuela     caracas       méxico
##   caballos.gan
## 1   victoreado
## 2  el comanche
## 3       wiso g
## 4     guadamur
## 5       hashin
## 6   nacozareño

Separar el pais del jinete y el nombre del jinete

En la tercera variable que me interesa cambiar solo me importa el nombre del jinete ganador

jinete <-as.character(caballos$jinete)
head(jinete)
## [1] " Venezuela Gustavo Ávila"     " México Rubén Contreras"     
## [3] " Puerto Rico Carlos López"    " México Alberto Zepeda"      
## [5] " México Miguel Yánez"         " Venezuela Guillermo Gavidia"
nombre<-sapply(strsplit(jinete, split="\\s"), "[[",3)
head(nombre)
## [1] "Gustavo"   "Rubén"     "Rico"      "Alberto"   "Miguel"    "Guillermo"
apellidos <-sapply(strsplit(jinete, split="\\s"), "[[",4)
head(apellidos)
## [1] "Ávila"     "Contreras" "Carlos"    "Zepeda"    "Yánez"     "Gavidia"

Hay que hacer algunos pasos adicionales para obtener el nombre

jinete.gan <-tolower(paste(nombre, apellidos))
head(jinete.gan)
## [1] "gustavo ávila"     "rubén contreras"   "rico carlos"      
## [4] "alberto zepeda"    "miguel yánez"      "guillermo gavidia"
#tenemos que modificar algunos nombres 3,15,16,24,26,27,34,38,40,41,43:45
# cambio los nombres asociados a puerto rico
a <-jinete[c(3, 15,16,24,26,27, 38, 40)]
a1<-sapply(strsplit(a, split="\\s"), "[[",4)
a1<-paste(a1, sapply(strsplit(a, split="\\s"), "[[",5))
a1[6]<-paste(a1[6], "garcia")
a1
## [1] "Carlos López"     "Juan Santiago"    "Santos Navarro"  
## [4] "Julio García"     "Juan Cintrón"     "Julio A. garcia" 
## [7] "Alexis Feliciano" "Héctor Berríos"
jinete.gan[c(3, 15,16,24,26,27, 38, 40)]<-a1

Hago lo mismo con los dos jinetes restantes

# Falta modifidcar 34, 41
jinete[c(34, 41)]
## [1] " los Estados Unidos Rosemary Homeister, Jr."
## [2] " la República Dominicana Joel Rosario"
jinete.gan[34] <-jinete.gan[34]<-
        paste(sapply(strsplit(jinete[34],
                split="\\s"),"[[",5),
                                   sapply(strsplit(jinete[34],
                                                   split="\\s"),
                                          "[[",6))
jinete.gan[41] <-jinete.gan[41]<-
        paste(sapply(strsplit(jinete[41],
                split="\\s"),"[[",5),
                                   sapply(strsplit(jinete[41],
                                                   split="\\s"),
                                          "[[",6))
jinete.gan <-tolower(jinete.gan)
head(jinete.gan)
## [1] "gustavo ávila"     "rubén contreras"   "carlos lópez"     
## [4] "alberto zepeda"    "miguel yánez"      "guillermo gavidia"

En el código anterior he seguido un camino distintos. Posiblemente más corto, pero probablemente menos obvio. Tomo directamente el elemento 34 de la variable ‘jinete.gan’, y separo, y simultáneamente pego, el nombre y apellido del jinete ganador. Para obtener el nombre del pais del jinete sigo un procedimiento similar:

pais.jinete<-sapply(strsplit(jinete, split="\\s"), "[[",2)

#modifico puerto rico, estados unidos y republica dominicana
b1<-sapply(strsplit(a, split="\\s"), "[[",2)
b1<-paste(b1, sapply(strsplit(a, split="\\s"), "[[",3))
b1
## [1] "Puerto Rico" "Puerto Rico" "Puerto Rico" "Puerto Rico" "Puerto Rico"
## [6] "Puerto Rico" "Puerto Rico" "Puerto Rico"
pais.jinete[c(3, 15,16,24,26,27, 38, 40)]<-b1

Modifico los dos paises restantes

# Falta modifidcar 34, 41
pais.jinete[c(34, 41)]
## [1] "los" "la"
pais.jinete[34] <-pais.jinete[34]<-
        paste(sapply(strsplit(jinete[34],
                split="\\s"),"[[",3),                                   sapply(strsplit(jinete[34],split="\\s"),
                                          "[[",4))
pais.jinete[41] <-pais.jinete[41]<-
        paste(sapply(strsplit(jinete[41],
                split="\\s"),"[[",3),                                   sapply(strsplit(jinete[41],split="\\s"),
                                          "[[",4))
pais.jinete <-tolower(pais.jinete)
head(pais.jinete)
## [1] "venezuela"   "méxico"      "puerto rico" "méxico"      "méxico"     
## [6] "venezuela"

Finalmente, agrego las dos columnas a mi marco de datos. Nótese que en lugar de agregar las columnas creadas al marco de datos existente, podría haber generado uno nuevo.

caballos <-data.frame(caballos, pais.jinete, jinete.gan)
head(caballos)
##    n. anio                     sede               ganador
## 1   I 1966     Puerto Rico San Juan  Venezuela Victoreado
## 2  II 1967        Venezuela Caracas    México El Comanche
## 3 III 1968     Puerto Rico San Juan   Puerto Rico Wiso G.
## 4  IV 1969  México Ciudad de México       México Guadamur
## 5   V 1970            Panamá Panamá         México Hashin
## 6  VI 1971        Venezuela Caracas     México Nacozareño
##                         jinete   sede.pais sede.ciudad pais.ganador
## 1      Venezuela Gustavo Ávila puerto rico    san.juan    venezuela
## 2       México Rubén Contreras   venezuela     caracas       méxico
## 3     Puerto Rico Carlos López puerto rico    san.juan  puerto.rico
## 4        México Alberto Zepeda      mexico cdad.mexico       méxico
## 5          México Miguel Yánez      panama      panama       méxico
## 6  Venezuela Guillermo Gavidia   venezuela     caracas       méxico
##   caballos.gan pais.jinete        jinete.gan
## 1   victoreado   venezuela     gustavo ávila
## 2  el comanche      méxico   rubén contreras
## 3       wiso g puerto rico      carlos lópez
## 4     guadamur      méxico    alberto zepeda
## 5       hashin      méxico      miguel yánez
## 6   nacozareño   venezuela guillermo gavidia

Caso 3. Variables guardadas con formato incorrecto

Estos casos se nos presentan cuando la variable se sube a R con un formato inadecuado o necesitamos un formato diferente:

  1. La data tiene apariencia de ser numérica, pero en realidad se ha subido como ‘factor’ o como ‘caracter’
  2. La data es numérica pero la necesito como ‘factor’ por ejemplo

Data como caracter

En el marco de datos sobre los delitos en el Distrito Capital la variable “km2” ha subido como caracter. Eso, en este caso, se debe a que la data se almacenó usando la coma como separador de decimal.

soluciono el caso de la variable km2

class(delitos_parroquiass$km2)
## [1] "character"
# cambio la coma por punto
delitos_parroquiass$km2<-gsub(",",
                              ".", delitos_parroquiass$km2)
delitos_parroquiass$km2[1:4]
## [1] "3.7"  "29.5" "1.2"  "9.9"
# llevo a numerico
delitos_parroquiass$km2 <-as.numeric(delitos_parroquiass$km2)
class(delitos_parroquiass$km2)
## [1] "numeric"
# el marco está listo para explorar y analizar
head(delitos_parroquiass)
##           parroquia total poblacion  km2 homicidio lesiones violacion
## 1        Altagracia   561     42946  3.7        19       85         0
## 2          Antímano  1558    146336 29.5       172      246       211
## 3        Candelaria  1127     60526  1.2        12       86         9
## 4    San Bernardino   727     26439  9.9        18       49         6
## 5          Caricuao  1696    162776 24.8        70      291       281
## 6       El Junquito   524     43696 56.0        31      107        21
##   contra.pers hurto hurto.auto robo robo.auto estafa violacion desval.veh
## 1          12   125         68  121        36     86         3          6
## 2          53   223        106  298       157     27        27         38
## 3           5   290        179  249        87    188         5         17
## 4          15   148        148  131       123     81         1          7
## 5          37   202        193  232       310     35        24         21
## 6          26    97         71   81        56     12        10         12

Fechas

Tengo un marco de datos en los que la fecha se ha guardado junto con valor ‘extraño’. Debo eliminar ese valor, y transformar la variable en fecha

head(esCantidad)
##       Años Total Oficial Privada
## 1 1980 (R)    74      49      25
## 2 1981 (R)    78      51      27
## 3 1982 (R)    83      54      29
## 4 1983 (R)    90      56      34
## 5 1984 (R)    90      56      34
## 6 1985 (R)    91      57      34
anios <-esCantidad$Años
anios[1:4]
## [1] 1980 (R) 1981 (R) 1982 (R) 1983 (R)
## 26 Levels: 1980 (R) 1981 (R) 1982 (R) 1983 (R) 1984 (R) ... 2005
# elimino (R)
anios <-gsub("\\(R\\)", "", anios)
anios[1:4]
## [1] "1980 " "1981 " "1982 " "1983 "
#elimino el espacio sobrante
anios <-str_trim(anios, "both")

#llevo a fecha.Agrega dia y mes con base en el dia en que
# se hace la conversion
class(anios)
## [1] "character"
anio<-as.Date(anios,format="%Y")
esCantidad <-data.frame(esCantidad, anio=substr(anio, 1,4))
head(esCantidad)
##       Años Total Oficial Privada anio
## 1 1980 (R)    74      49      25 1980
## 2 1981 (R)    78      51      27 1981
## 3 1982 (R)    83      54      29 1982
## 4 1983 (R)    90      56      34 1983
## 5 1984 (R)    90      56      34 1984
## 6 1985 (R)    91      57      34 1985