1  Manipulación de data frame

1.1 Funciones, Módulos y Librerías principales en R

1.2 Funciones y módulos

- Funciones y Scripts: Puedes dividir tu código en funciones y scripts separados para organizarlo de manera más clara y reutilizable. Cada script podría contener un conjunto de funciones relacionadas entre sí.

- Paquetes: La construcción de paquetes es una forma poderosa de modularizar el código en R. Los paquetes son conjuntos de funciones, datos y documentación que se distribuyen para un propósito específico y se pueden compartir con otros usuarios. Puedes crear tus propios paquetes para organizar y compartir tu código de manera efectiva.

- Los paquetes en R son colecciones de funciones y conjunto de datos desarrollados por la comunidad. Estos incrementan la potencialidad de R mejorando las funcionalidades base en R, o añadiendo de nuevas. Por ejemplo, en el campo de Ciencia de los Datos cuando trabajamos con data.frames, probablemente usaremos los paquetes dplyr o data.table, dos de los paquetes mas populares en la comunidad.

- En R Studio, no necesitas una librería específica para importar módulos. Puedes utilizar la función source() que viene integrada en R para cargar funciones, scripts o módulos desde archivos externos. La función source() permite ejecutar código desde un archivo R en tu sesión actual. Por ejemplo, si tienes un archivo llamado “funciones.R” con las funciones que mencionamos anteriormente, puedes importar ese archivo utilizando source() de esta manera:

source("ruta/al/archivo/funciones.R") # Reemplaza con la ruta correcta de tu archivo`

1.2.1 Caso uno usando funciones

# Cargar las funciones desde el archivo funciones.R

source("C:/Users/PC/Desktop/PLE/Manipulación de dataframe/a/funciones.r")

Ahora usando el módulo de “Funciones.r” para hacer calculos con números direrentes

# Ahora las funciones están disponibles para su uso en R Studio

resultado_suma <- Suma5(1, 2, 3, 4, 5)

resultados_potencia <- Potencia5(1, 2, 3, 4, 5)

resultados_raiz <- Raiz5(1, 4, 9, 16, 25)

varianza_resultado <- Varianza5(1, 2, 3, 4, 5)

Imprimimos resultados de la funciones

# Imprimimos resultados de la funciones 

print(resultado_suma)
[1] 15
print(resultados_potencia)
[1]  1  4  9 16 25
print(resultados_raiz)
[1] 1 2 3 4 5
print(varianza_resultado)
[1] 2.5
# Ejemplo de uso de las nuevas funciones

resultado_seno <- Seno(pi/2)

resultado_coseno <- Coseno(0)

resultado_log <- Logaritmo(10)

resultado_factorial <- Factorial(5)
print(resultado_seno)
[1] 1
print(resultado_coseno)
[1] 1
print(resultado_log)
[1] 2.302585
print(resultado_factorial)
[1] 120

1.2.1.1 Ejemplo: Aplicación de funciones trigonométricas en arquitectura

Imagina que estás trabajando como arquitecto/a y necesitas diseñar una rampa para un edificio que cumpla con ciertas especificaciones. Utilizarás funciones trigonométricas para calcular la longitud de la rampa, la altura y la pendiente necesarias para asegurar la accesibilidad.

Supongamos que necesitas diseñar una rampa para un edificio con una altura vertical de 5 metros y quieres que la rampa tenga un ángulo de inclinación específico para que sea cómoda para los peatones.

Cálculo de la longitud de la rampa:

Utilizamos funciones trigonométricas para calcular la longitud de la rampa basada en la altura vertical y el ángulo de inclinación deseado.

Altura <- 5  # Altura del edificio en metros

Angulo <- 10  # Ángulo de inclinación en grados

# Convertir el ángulo a radianes para usar funciones trigonométricas en R

Angulo_radianes <- Angulo * (pi / 180)

Angulo_radianes
[1] 0.1745329
# Calcular la longitud de la rampa usando trigonometría (hipotenusa)

Longitud_rampa <- Altura / sin(Angulo_radianes)

Longitud_rampa
[1] 28.79385

Cálculo de la pendiente de la rampa:

La pendiente es la relación entre la altura y la longitud de la rampa.

# Calcular la pendiente de la rampa

Pendiente <- Altura / Longitud_rampa

Pendiente
[1] 0.1736482

1.2.1.2 Ejemplo: Modelado del crecimiento poblacional

Imagina que eres un biólogo que estudia el crecimiento de una población de bacterias en un entorno controlado. Las bacterias se reproducen cada cierto período de tiempo, y quieres modelar este crecimiento utilizando funciones exponenciales.

Supongamos que has observado que, en tu entorno controlado, el número de bacterias se duplica cada 2 horas. Utilizarás una función exponencial para modelar este crecimiento.

Solución:

La fórmula exponencial que describe el crecimiento de las bacterias es:

\(N(t) = N_0 \times e^{rt}\)

Donde:

- \(N(t)\) es el número de bacterias en el tiempo \(t\).

- \(N_0\) es el número inicial de bacterias.

- \(r\) es la tasa de crecimiento.

- \(e\) es la base del logaritmo natural.

- \(t\) es el tiempo.

Supogamos que inicialmente se tiene 100 bacterias

# Definir la función exponencial para el crecimiento de las bacterias

CrecimientoBacterias <- function(t) {

N0 <- 100 # Número inicial de bacterias

r <- log(2) / 2 # La población se duplica cada 2 horas (log(2) / 2)

Nt <- N0 * exp(r * t)

return(Nt)

}

Gráfico del crecimiento de las bacterias:

Puedes crear un gráfico para visualizar cómo crece la población de bacterias en función del tiempo.

# Crear un vector de tiempos (por ejemplo, de 0 a 10 horas)

tiempo <- seq(0, 10, by = 0.5)

# Calcular el número de bacterias en cada tiempo

poblacion <- sapply(tiempo, CrecimientoBacterias)

# Graficar el crecimiento de las bacterias en función del tiempo

plot(tiempo, poblacion, type = "l", xlab = "Tiempo (horas)", ylab = "Número de bacterias",

main = "Crecimiento de bacterias en función del tiempo")

1.3 Librerías

En R, una librería (también conocida como paquete) es un conjunto de funciones, datos y documentación que extiende la funcionalidad del lenguaje base. Estos paquetes son desarrollados por la comunidad de R y permiten a los usuarios acceder a una amplia gama de herramientas y funcionalidades especializadas para diferentes tipos de análisis y tareas.

Puedes utilizar la función install.packages() para instalar un paquete en R, y luego la función library() para cargarlo y utilizar sus funciones en tu sesión actual. Por ejemplo:

install.packages("nombre_del_paquete")

Reemplaza “nombre_del_paquete” con el nombre del paquete que quieras instalar, por ejemplo: install.packages("ggplot2") instalará el paquete ggplot2 para gráficos. Para cargar un paquete se usa library()

library("nombre_del_paquete")

1.4 Dataframe, Manipulación e Introducción al análisis de datos.

La manipulación de data frames significa distintas cosas para distintos investigadores. A veces queremos seleccionar ciertas observaciones (filas) o variables (columnas), otras veces deseamos agrupar los datos en función de una o más variables, o queremos calcular valores estadísticos de un conjunto. Podemos hacer todo ello usando las habituales operaciones básicas de R:

EJEMPLOS:

#Data Frame

##caso 1

x=c('a','b','c','d')

x1=c(20,32,53,56)

x2=c('masculino','femenino','masculino','masculino')

DataFrame1=data.frame(casos=x,edadDeCasos=x1,sexoDecasos=x2)

Luego de correrlo, vemos en Environment que este código creó tres vectores. Un vector (x) tiene los nombres o IDs de las filas. Los nombres de los vectores (“x”,“x1”,“x2”) no son informativos de sus contenidos de datos. El comando data.frame enlaza a todos los tres vectores como columnas y nos brinda un nombre explícito para cada columna.

Para ver el data frame generado, correr el siguiente código:

DataFrame1
  casos edadDeCasos sexoDecasos
1     a          20   masculino
2     b          32    femenino
3     c          53   masculino
4     d          56   masculino
##caso 2
casos=c('a','b','c','d')

edadDeCasos=c(20,32,53,56)

sexoDeCasos=c('masculino','femenino','masculino','masculino')

DataFrame2=data.frame(edadDeCasos,sexoDeCasos,row.names=casos)

Luego de correrlo, vemos en Environment que este código creó tres vectores. Un vector (casos) tiene los nombres o IDs de las filas. Los nombres de los vectores (“casos”,“edadDeCasos”,“sexoDeCasos”) informan acerca de qué tratan sus contenidos. El comando data.frame enlaza los vectores como columnas, y los nombres de los vectores son los nombres de las columnas en el data frame. [Notar el uso de la opción `row.names`]

Para ver el data frame generado, correr el siguiente código:

DataFrame2
  edadDeCasos sexoDeCasos
a          20   masculino
b          32    femenino
c          53   masculino
d          56   masculino
##caso3
a=list(edadDeCasos=20,sexoDeCasos='masculino')

b=list(edadDeCasos=32,sexoDeCasos='femenino')

c=list(edadDeCasos=53,sexoDeCasos='masculino')

d=list(edadDeCasos=56,sexoDeCasos='masculino')

DataFrame3=data.frame(rbind(a,b,c,d))

Luego de correrlo, vemos en Environment que este código creó cuatro listas (“a”,“b”,“c”,“d”). Cada lista tiene la información de la entrada de una fila. Cada elemento de la lista asocia cada valor a una variable. El comando data.frame enlaza todas las listas como filas, con la ayuda del comando rbind. Esta última es una forma alternativa de crear data frames, en caso tengas los datos por unidad de análisis (vale decir, por filas).

DataFrame3
  edadDeCasos sexoDeCasos
a          20   masculino
b          32    femenino
c          53   masculino
d          56   masculino

Ejemplo con github

# Descargar el archivo RData desde GitHub
url <- "https://github.com/hllinas/DatosPublicos/raw/main/Estudiantes.Rdata"

dest_file <- "Estudiantes.Rdata"

download.file(url, dest_file, mode = "wb")

# Cargar los datos desde el archivo RData descargado
load("Estudiantes.Rdata")

# Verificar los nombres de los objetos cargados
ls()
 [1] "a"                    "Altura"               "Angulo"              
 [4] "Angulo_radianes"      "b"                    "c"                   
 [7] "casos"                "Coseno"               "CrecimientoBacterias"
[10] "d"                    "DataFrame1"           "DataFrame2"          
[13] "DataFrame3"           "dest_file"            "edadDeCasos"         
[16] "Estudiantes"          "Factorial"            "has_annotations"     
[19] "Logaritmo"            "Longitud_rampa"       "Pendiente"           
[22] "poblacion"            "Potencia5"            "Raiz5"               
[25] "resultado_coseno"     "resultado_factorial"  "resultado_log"       
[28] "resultado_seno"       "resultado_suma"       "resultados_potencia" 
[31] "resultados_raiz"      "Seno"                 "sexoDeCasos"         
[34] "Suma5"                "tiempo"               "url"                 
[37] "varianza_resultado"   "Varianza5"            "x"                   
[40] "x1"                   "x2"                  
# Si "Estudiantes" es el nombre del objeto que contiene los datos
datosCompleto <- Estudiantes

Ejemplo de Drive

url.dat<- "http://bit.ly/Database-Estudiantes"

datosCompleto <- read.delim(url.dat)

Visualizar una parte de la información

head(datosCompleto) #2) Por defecto, solo las primeras 6 observaciones
  Observacion               ID      Sexo SexoNum  Edad Fuma Estatura Colegio
1           1 SB11201910010435  Femenino       0 21.36   No     Alta Privado
2           2 SB11201910004475 Masculino       1 21.07   Si     Baja Privado
3           3 SB11201910011427 Masculino       1 20.92   Si     Alta Privado
4           4 SB11201910041975 Masculino       1 18.41   Si     Alta Privado
5           5 SB11201910013623  Femenino       0 16.64   Si     Alta Privado
6           6 SB11201910038122  Femenino       0 16.02   No     Baja Privado
  Estrato Financiacion Acumulado  P1  P2  P3 Final Definitiva Gastos Ingreso
1       1         Beca      3.92 1.5 5.0 5.0   4.5       4.00   48.9    1.61
2       2         Beca      3.96 2.3 4.9 3.7   3.3       3.55   72.1    2.07
3       2         Beca      3.85 3.4 3.6 2.0   1.9       2.73   85.2    2.84
4       2         Beca      3.69 2.5 4.2 5.0   2.5       3.55   56.6    1.55
5       1         Beca      4.01 3.1 3.5 5.0   3.0       3.65   64.6    2.32
6       2         Beca      3.80 3.8 4.4 4.2   5.0       4.35   63.0    2.10
    Gas     Clases           Ley                     PandemiaCat PandemiaNum
1 27.45    Virtual En desacuerdo                      De acuerdo           3
2 24.17 Presencial En desacuerdo                      De acuerdo           3
3 22.27    Virtual En desacuerdo                      De acuerdo           3
4 23.08    Virtual En desacuerdo                      De acuerdo           3
5 27.26    Virtual En desacuerdo Ni de acuerdo, ni en desacuerdo           2
6 17.16 Presencial    De acuerdo                      De acuerdo           3
  Likert1 Likert2 Likert3 Likert4 Likert5                          AGPEQ1
1       4       5       1       3       1           Totalmente de acuerdo
2       3       2       4       3       2 Ni de acuerdo, ni en desacuerdo
3       2       3       3       4       2                      De acuerdo
4       5       4       2       3       5                      De acuerdo
5       1       1       5       2       5           Totalmente de acuerdo
6       3       2       3       1       1                      De acuerdo
                           AGPEQ2                   AGPEQ3
1                      De acuerdo    Totalmente de acuerdo
2                   En desacuerdo            En desacuerdo
3                   En desacuerdo               De acuerdo
4 Ni de acuerdo, ni en desacuerdo    Totalmente de acuerdo
5 Ni de acuerdo, ni en desacuerdo Totalmente en desacuerdo
6                   En desacuerdo            En desacuerdo
                     SATS1                 SATS2         SATS3
1                 Indeciso            De acuerdo En desacuerdo
2            En desacuerdo            De acuerdo      Indeciso
3            En desacuerdo Totalmente de acuerdo      Indeciso
4 Totalmente en desacuerdo Totalmente de acuerdo En desacuerdo
5                 Indeciso            De acuerdo En desacuerdo
6               De acuerdo              Indeciso En desacuerdo
                     SATS4 IDARE1.1          IDARE1.2 IDARE1.3
1               De acuerdo Bastante              Poco Bastante
2 Totalmente en desacuerdo Bastante              Poco    Mucho
3               De acuerdo Bastante              Poco Bastante
4               De acuerdo     Poco No en lo absoluto Bastante
5                 Indeciso     Poco              Poco Bastante
6               De acuerdo    Mucho             Mucho     Poco
           IDARE1.4          IDARE1.5       IDARE2.6       IDARE2.7
1          Bastante              Poco Frecuentemente   Casi siempre
2 No en lo absoluto          Bastante Frecuentemente  Algunas veces
3          Bastante              Poco  Algunas veces  Algunas veces
4          Bastante No en lo absoluto   Casi siempre Frecuentemente
5          Bastante              Poco  Algunas veces  Algunas veces
6 No en lo absoluto             Mucho   Casi siempre     Casi nunca
        IDARE2.8       IDARE2.9      IDARE2.10 Puntaje
1 Frecuentemente   Casi siempre   Casi siempre      81
2  Algunas veces Frecuentemente Frecuentemente      78
3  Algunas veces Frecuentemente  Algunas veces      77
4 Frecuentemente     Casi nunca  Algunas veces      70
5 Frecuentemente     Casi nunca     Casi nunca      68
6  Algunas veces  Algunas veces Frecuentemente      65
head(datosCompleto, 3) #3) Solo las primeras 3 observaciones
  Observacion               ID      Sexo SexoNum  Edad Fuma Estatura Colegio
1           1 SB11201910010435  Femenino       0 21.36   No     Alta Privado
2           2 SB11201910004475 Masculino       1 21.07   Si     Baja Privado
3           3 SB11201910011427 Masculino       1 20.92   Si     Alta Privado
  Estrato Financiacion Acumulado  P1  P2  P3 Final Definitiva Gastos Ingreso
1       1         Beca      3.92 1.5 5.0 5.0   4.5       4.00   48.9    1.61
2       2         Beca      3.96 2.3 4.9 3.7   3.3       3.55   72.1    2.07
3       2         Beca      3.85 3.4 3.6 2.0   1.9       2.73   85.2    2.84
    Gas     Clases           Ley PandemiaCat PandemiaNum Likert1 Likert2
1 27.45    Virtual En desacuerdo  De acuerdo           3       4       5
2 24.17 Presencial En desacuerdo  De acuerdo           3       3       2
3 22.27    Virtual En desacuerdo  De acuerdo           3       2       3
  Likert3 Likert4 Likert5                          AGPEQ1        AGPEQ2
1       1       3       1           Totalmente de acuerdo    De acuerdo
2       4       3       2 Ni de acuerdo, ni en desacuerdo En desacuerdo
3       3       4       2                      De acuerdo En desacuerdo
                 AGPEQ3         SATS1                 SATS2         SATS3
1 Totalmente de acuerdo      Indeciso            De acuerdo En desacuerdo
2         En desacuerdo En desacuerdo            De acuerdo      Indeciso
3            De acuerdo En desacuerdo Totalmente de acuerdo      Indeciso
                     SATS4 IDARE1.1 IDARE1.2 IDARE1.3          IDARE1.4
1               De acuerdo Bastante     Poco Bastante          Bastante
2 Totalmente en desacuerdo Bastante     Poco    Mucho No en lo absoluto
3               De acuerdo Bastante     Poco Bastante          Bastante
  IDARE1.5       IDARE2.6      IDARE2.7       IDARE2.8       IDARE2.9
1     Poco Frecuentemente  Casi siempre Frecuentemente   Casi siempre
2 Bastante Frecuentemente Algunas veces  Algunas veces Frecuentemente
3     Poco  Algunas veces Algunas veces  Algunas veces Frecuentemente
       IDARE2.10 Puntaje
1   Casi siempre      81
2 Frecuentemente      78
3  Algunas veces      77
tail(datosCompleto) #4) Por defecto, solo las últimas 6 observaciones
    Observacion               ID      Sexo SexoNum  Edad Fuma Estatura Colegio
395         395 SB11201910060914  Femenino       0 16.54   Si    Media Publico
396         396 SB11201910040869 Masculino       1 17.97   No    Media Publico
397         397 SB11201910040887 Masculino       1 17.22   Si    Media Publico
398         398 SB11201910040981  Femenino       0 20.41   No    Media Publico
399         399 SB11201910040935  Femenino       0 18.72   Si    Media Publico
400         400 SB11201910043103 Masculino       1 17.04   Si    Media Publico
    Estrato Financiacion Acumulado  P1  P2  P3 Final Definitiva Gastos Ingreso
395       3         Otro      4.04 4.0 4.8 3.0   3.1       3.73   33.6    1.12
396       3         Otro      4.15 4.5 5.0 3.3   1.9       3.68   62.6    2.42
397       3         Otro      3.90 5.0 3.8 4.2   3.9       4.23   41.4    1.39
398       3         Otro      3.64 3.5 3.6 3.8   4.9       3.95   40.8    1.36
399       1         Otro      4.42 4.9 5.0 4.4   3.3       4.40   53.3    2.11
400       1         Otro      3.45 2.5 4.3 3.9   4.5       3.80   56.8    1.89
      Gas     Clases           Ley                     PandemiaCat PandemiaNum
395 19.46    Virtual En desacuerdo                      De acuerdo           3
396 16.02 Presencial En desacuerdo                   En desacuerdo           1
397 17.04 Presencial    De acuerdo Ni de acuerdo, ni en desacuerdo           2
398 20.83 Presencial    De acuerdo                      De acuerdo           3
399 18.72    Virtual En desacuerdo                   En desacuerdo           1
400 18.45 Presencial    De acuerdo Ni de acuerdo, ni en desacuerdo           2
    Likert1 Likert2 Likert3 Likert4 Likert5                AGPEQ1
395       1       1       4       4       3            De acuerdo
396       2       1       3       4       1            De acuerdo
397       5       2       3       2       3            De acuerdo
398       1       5       2       5       1            De acuerdo
399       2       3       5       1       1         En desacuerdo
400       1       2       2       2       3 Totalmente de acuerdo
                             AGPEQ2                          AGPEQ3
395        Totalmente en desacuerdo                   En desacuerdo
396 Ni de acuerdo, ni en desacuerdo Ni de acuerdo, ni en desacuerdo
397                      De acuerdo                      De acuerdo
398 Ni de acuerdo, ni en desacuerdo Ni de acuerdo, ni en desacuerdo
399           Totalmente de acuerdo        Totalmente en desacuerdo
400                   En desacuerdo        Totalmente en desacuerdo
                    SATS1                    SATS2                    SATS3
395 Totalmente de acuerdo                 Indeciso Totalmente en desacuerdo
396            De acuerdo                 Indeciso            En desacuerdo
397            De acuerdo            En desacuerdo            En desacuerdo
398 Totalmente de acuerdo            En desacuerdo            En desacuerdo
399            De acuerdo               De acuerdo                 Indeciso
400            De acuerdo Totalmente en desacuerdo            En desacuerdo
            SATS4 IDARE1.1 IDARE1.2 IDARE1.3          IDARE1.4 IDARE1.5
395    De acuerdo    Mucho    Mucho     Poco              Poco Bastante
396 En desacuerdo    Mucho Bastante     Poco No en lo absoluto Bastante
397    De acuerdo Bastante Bastante     Poco No en lo absoluto Bastante
398      Indeciso     Poco Bastante     Poco No en lo absoluto    Mucho
399 En desacuerdo     Poco     Poco    Mucho          Bastante     Poco
400    De acuerdo Bastante     Poco     Poco              Poco     Poco
          IDARE2.6       IDARE2.7       IDARE2.8      IDARE2.9     IDARE2.10
395  Algunas veces  Algunas veces  Algunas veces Algunas veces Algunas veces
396 Frecuentemente Frecuentemente Frecuentemente    Casi nunca    Casi nunca
397 Frecuentemente  Algunas veces     Casi nunca    Casi nunca Algunas veces
398   Casi siempre     Casi nunca     Casi nunca    Casi nunca    Casi nunca
399 Frecuentemente  Algunas veces  Algunas veces    Casi nunca    Casi nunca
400   Casi siempre  Algunas veces     Casi nunca Algunas veces Algunas veces
    Puntaje
395      27
396      19
397      18
398      15
399      17
400      19
tail(datosCompleto, 2) #5) Solo las últimas 2 observaciones
    Observacion               ID      Sexo SexoNum  Edad Fuma Estatura Colegio
399         399 SB11201910040935  Femenino       0 18.72   Si    Media Publico
400         400 SB11201910043103 Masculino       1 17.04   Si    Media Publico
    Estrato Financiacion Acumulado  P1  P2  P3 Final Definitiva Gastos Ingreso
399       1         Otro      4.42 4.9 5.0 4.4   3.3        4.4   53.3    2.11
400       1         Otro      3.45 2.5 4.3 3.9   4.5        3.8   56.8    1.89
      Gas     Clases           Ley                     PandemiaCat PandemiaNum
399 18.72    Virtual En desacuerdo                   En desacuerdo           1
400 18.45 Presencial    De acuerdo Ni de acuerdo, ni en desacuerdo           2
    Likert1 Likert2 Likert3 Likert4 Likert5                AGPEQ1
399       2       3       5       1       1         En desacuerdo
400       1       2       2       2       3 Totalmente de acuerdo
                   AGPEQ2                   AGPEQ3      SATS1
399 Totalmente de acuerdo Totalmente en desacuerdo De acuerdo
400         En desacuerdo Totalmente en desacuerdo De acuerdo
                       SATS2         SATS3         SATS4 IDARE1.1 IDARE1.2
399               De acuerdo      Indeciso En desacuerdo     Poco     Poco
400 Totalmente en desacuerdo En desacuerdo    De acuerdo Bastante     Poco
    IDARE1.3 IDARE1.4 IDARE1.5       IDARE2.6      IDARE2.7      IDARE2.8
399    Mucho Bastante     Poco Frecuentemente Algunas veces Algunas veces
400     Poco     Poco     Poco   Casi siempre Algunas veces    Casi nunca
         IDARE2.9     IDARE2.10 Puntaje
399    Casi nunca    Casi nunca      17
400 Algunas veces Algunas veces      19

Explorar atributos y funciones

str(datosCompleto) #6) Estructura de los datos
'data.frame':   400 obs. of  46 variables:
 $ Observacion : int  1 2 3 4 5 6 7 8 9 10 ...
 $ ID          : chr  "SB11201910010435" "SB11201910004475" "SB11201910011427" "SB11201910041975" ...
 $ Sexo        : chr  "Femenino" "Masculino" "Masculino" "Masculino" ...
 $ SexoNum     : int  0 1 1 1 0 0 0 0 0 1 ...
 $ Edad        : num  21.4 21.1 20.9 18.4 16.6 ...
 $ Fuma        : chr  "No" "Si" "Si" "Si" ...
 $ Estatura    : chr  "Alta" "Baja" "Alta" "Alta" ...
 $ Colegio     : chr  "Privado" "Privado" "Privado" "Privado" ...
 $ Estrato     : int  1 2 2 2 1 2 1 1 2 1 ...
 $ Financiacion: chr  "Beca" "Beca" "Beca" "Beca" ...
 $ Acumulado   : num  3.92 3.96 3.85 3.69 4.01 3.8 4.35 3.76 3.57 3.15 ...
 $ P1          : num  1.5 2.3 3.4 2.5 3.1 3.8 5 4 2.5 2.4 ...
 $ P2          : num  5 4.9 3.6 4.2 3.5 4.4 3 2.3 3.3 2.6 ...
 $ P3          : num  5 3.7 2 5 5 4.2 3.5 4.6 3.8 4.3 ...
 $ Final       : num  4.5 3.3 1.9 2.5 3 5 3.6 4.3 1.9 5 ...
 $ Definitiva  : num  4 3.55 2.73 3.55 3.65 4.35 3.78 3.8 2.88 3.58 ...
 $ Gastos      : num  48.9 72.1 85.2 56.6 64.6 63 40.8 65.4 37.3 63 ...
 $ Ingreso     : num  1.61 2.07 2.84 1.55 2.32 2.1 1.69 2.18 1.71 2.1 ...
 $ Gas         : num  27.4 24.2 22.3 23.1 27.3 ...
 $ Clases      : chr  "Virtual" "Presencial" "Virtual" "Virtual" ...
 $ Ley         : chr  "En desacuerdo" "En desacuerdo" "En desacuerdo" "En desacuerdo" ...
 $ PandemiaCat : chr  "De acuerdo" "De acuerdo" "De acuerdo" "De acuerdo" ...
 $ PandemiaNum : int  3 3 3 3 2 3 3 3 1 3 ...
 $ Likert1     : int  4 3 2 5 1 3 4 1 2 5 ...
 $ Likert2     : int  5 2 3 4 1 2 3 2 1 4 ...
 $ Likert3     : int  1 4 3 2 5 3 3 3 4 1 ...
 $ Likert4     : int  3 3 4 3 2 1 4 3 2 5 ...
 $ Likert5     : int  1 2 2 5 5 1 2 2 5 2 ...
 $ AGPEQ1      : chr  "Totalmente de acuerdo" "Ni de acuerdo, ni en desacuerdo" "De acuerdo" "De acuerdo" ...
 $ AGPEQ2      : chr  "De acuerdo" "En desacuerdo" "En desacuerdo" "Ni de acuerdo, ni en desacuerdo" ...
 $ AGPEQ3      : chr  "Totalmente de acuerdo" "En desacuerdo" "De acuerdo" "Totalmente de acuerdo" ...
 $ SATS1       : chr  "Indeciso" "En desacuerdo" "En desacuerdo" "Totalmente en desacuerdo" ...
 $ SATS2       : chr  "De acuerdo" "De acuerdo" "Totalmente de acuerdo" "Totalmente de acuerdo" ...
 $ SATS3       : chr  "En desacuerdo" "Indeciso" "Indeciso" "En desacuerdo" ...
 $ SATS4       : chr  "De acuerdo" "Totalmente en desacuerdo" "De acuerdo" "De acuerdo" ...
 $ IDARE1.1    : chr  "Bastante" "Bastante" "Bastante" "Poco" ...
 $ IDARE1.2    : chr  "Poco" "Poco" "Poco" "No en lo absoluto" ...
 $ IDARE1.3    : chr  "Bastante" "Mucho" "Bastante" "Bastante" ...
 $ IDARE1.4    : chr  "Bastante" "No en lo absoluto" "Bastante" "Bastante" ...
 $ IDARE1.5    : chr  "Poco" "Bastante" "Poco" "No en lo absoluto" ...
 $ IDARE2.6    : chr  "Frecuentemente" "Frecuentemente" "Algunas veces" "Casi siempre" ...
 $ IDARE2.7    : chr  "Casi siempre" "Algunas veces" "Algunas veces" "Frecuentemente" ...
 $ IDARE2.8    : chr  "Frecuentemente" "Algunas veces" "Algunas veces" "Frecuentemente" ...
 $ IDARE2.9    : chr  "Casi siempre" "Frecuentemente" "Frecuentemente" "Casi nunca" ...
 $ IDARE2.10   : chr  "Casi siempre" "Frecuentemente" "Algunas veces" "Algunas veces" ...
 $ Puntaje     : int  81 78 77 70 68 65 54 50 36 35 ...
class(datosCompleto) #7) Muestra el tipo de objeto.
[1] "data.frame"
names(datosCompleto) #8) Muestra los nombres de las columnas.
 [1] "Observacion"  "ID"           "Sexo"         "SexoNum"      "Edad"        
 [6] "Fuma"         "Estatura"     "Colegio"      "Estrato"      "Financiacion"
[11] "Acumulado"    "P1"           "P2"           "P3"           "Final"       
[16] "Definitiva"   "Gastos"       "Ingreso"      "Gas"          "Clases"      
[21] "Ley"          "PandemiaCat"  "PandemiaNum"  "Likert1"      "Likert2"     
[26] "Likert3"      "Likert4"      "Likert5"      "AGPEQ1"       "AGPEQ2"      
[31] "AGPEQ3"       "SATS1"        "SATS2"        "SATS3"        "SATS4"       
[36] "IDARE1.1"     "IDARE1.2"     "IDARE1.3"     "IDARE1.4"     "IDARE1.5"    
[41] "IDARE2.6"     "IDARE2.7"     "IDARE2.8"     "IDARE2.9"     "IDARE2.10"   
[46] "Puntaje"     
help(datosCompleto) #9) Muestra la ayuda asociada para el archivo de datos (si la hay).
No documentation for 'datosCompleto' in specified packages and libraries:
you could try '??datosCompleto'
??datosCompleto #10) Muestra la ayuda asociada para el archivo de datos en la web (si la hay).
starting httpd help server ... done

Verificar tamaños

length(datosCompleto) #11) Revisando número de variables del objeto
[1] 46
dim(datosCompleto) #12) Muestra las dimensiones del objeto.
[1] 400  46
ncol(datosCompleto) #13) Muestra el número de columnas del objeto.
[1] 46
nrow(datosCompleto) #14) Muestra el número de filas del objeto.
[1] 400

1.5 Análisis de datos

Vamos a trabajar con un conjunto de datos que recoge asociaciones mentales con la expresión “Big data”. Este conjunto se forma a partir de respuestas a una breve encuesta que solicitaba palabras o frases asociadas a esta expresión, junto con la valoración positiva o negativa de dichas ideas. También registramos el orden en que se introdujeron las palabras, normalmente entre 1 y 5, aunque los participantes podían agregar más términos.

Usando este conjunto de datos y siguiendo las tareas descritas, nuestro objetivo es descubrir las ideas predominantes sobre el big data. Este enfoque se enmarca en la psicología social, específicamente en la teoría de la representación social, adoptando la perspectiva estructural de Abric (2001) y empleando métodos cuantitativos. Al final del análisis, llevaremos a cabo un “análisis prototípico” de esta teoría y debatiremos la interpretación de los resultados.

1.5.1 Cargar datos y recursos

Lo primero que haremos es cargar algunas librerias (package) que van a poner a nuestra disposición un conjunto de funciones que utilizaremos a lo largo de todo el ejercicio. Recordá que una función es una secuencia de comandos que se aplican a un objeto que se le pasa a la función, referenciándolo entre sus paréntesis. Por ejemplo, utilizaremos la función `library()` y el nombre de las librerías para habilitar las funciones de readr para importar datos, y el conjunto de librerías del tidyverse para manipular y visualizar.

# una vez instaladas hay que cargarlas en memoria

library(readr)

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.3     ✔ purrr     1.0.2
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.4.4     ✔ tibble    3.2.1
✔ lubridate 1.9.3     ✔ tidyr     1.3.0
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors

Luego importaremos los datos con la función read_csv() de la librería readr. En RStudio podés listar a las funciones de un paquete si tipeas su nombre seguido de ::. Esta forma de vincular paquetes y funciones es recomendada, en tanto los nombres de las funciones pueden pisarse, dependiendo del orden en que cargamos los paquetes.

Nos interesa que esos datos importados se guarden como un objeto en memoria, ya que estaremos trabajando con ellos en lo que sigue. Para ello, utilizamos un operador de asignación <- , precedido del nombre que le daremos al objeto (en nuestro caso asociaciones).

asociaciones <- readr::read_csv(file = "https://raw.githubusercontent.com/gastonbecerra/curso-intro-r/main/data/asociaciones.csv")
Rows: 1707 Columns: 4
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (2): id, palabra
dbl (2): orden, valoracion

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

1.5.2 Exploración de datos

El objetivo del momento de exploración de los datos es familiarizarnos con la estructura de los datos, y transformarlos para poder realizar nuestros análisis. Por lo general, aquí se empiezan a decidir las tareas de limpieza.

Lo primero que vamos a hacer es ver el tamaño de la tabla con dim(), y los primeros registros con head().

Esto nos va a permitir saber:

-la cantidad de registros y columnas;

- los nombres de las columnas y su tipo de dato;

- el contenido de los primeros registros.

dim(asociaciones)
[1] 1707    4
head(asociaciones, n = 10)
# A tibble: 10 × 4
   id                   palabra       orden valoracion
   <chr>                <chr>         <dbl>      <dbl>
 1 -M0-9OQkabuGoSmceB5E información       1          5
 2 -M0-9OQkabuGoSmceB5E análisis          2          5
 3 -M0-9OQkabuGoSmceB5E investigación     3          5
 4 -M0-9OQkabuGoSmceB5E comercial         4          4
 5 -M0-9OQkabuGoSmceB5E filtración        5         -5
 6 -M0U7_pJAU9Ehga0LIWq información       1          5
 7 -M0U7_pJAU9Ehga0LIWq tecnología        2          5
 8 -M0U7_pJAU9Ehga0LIWq sistemas          3          5
 9 -M0U7_pJAU9Ehga0LIWq computadora       4          0
10 -M0U7_pJAU9Ehga0LIWq freaks            5         -3

Por lo que podemos ver, tenemos 4 columas: `id` y palabra son variables de texto (`<chr>`), mientras `orden` y `valoracion` son numéricas. Otro posible tipo de columna es el factor (`<fct>`) que sirve para registrar categorías, donde cada valor posible es un level.

Podemos ver que el valor de id se repite entre filas, lo que nos da la pauta que varios registros corresponden naturalmente juntos. En este caso, se tratan de las distintas palabras mencionadas por un mismo participante frente a “big data”. Este diseño de tabla donde hay n registros x 1 participante, a diferencia de tener sólo registro con muchas columnas tiene muchas ventajas. Por el momento señalemos sólo 1: todas nuestras palabras quedan en la misma columna, de modo que si queremos procesarlas será muy fácil referenciarlas. Cada palabra propuesta tiene, además, el orden de evocación (`orden`) y la valoración dada (`valoracion`).

Luego, es útil tener una idea de los valores posibles de las distintas columnas o variables. `summary` nos devuelve un resumen de estadísticas descriptivas, que nos permite saber, por ejemplo, en qué rango se registran las valoraciones, o cómo se distribuyen los ordenes de evocación.

summary(asociaciones)
      id              palabra              orden         valoracion    
 Length:1707        Length:1707        Min.   : 1.00   Min.   :-5.000  
 Class :character   Class :character   1st Qu.: 2.00   1st Qu.:-1.000  
 Mode  :character   Mode  :character   Median : 3.00   Median : 1.000  
                                       Mean   : 3.06   Mean   : 1.053  
                                       3rd Qu.: 4.00   3rd Qu.: 5.000  
                                       Max.   :14.00   Max.   : 5.000  

Otras tareas que nos pueden interesar en el análisis exploratorios son:

- ver la cantidad de datos vacíosview(asociaciones)

- ver la cantidad de datos redundantes

- ver relaciones entre variables

- graficar el rango de valores de una o más variables

Recordá que podes ver la tabla, como si estuvieras viendo una planilla, con `view(asociaciones)`.

1.5.3 Transformar, visualizar y limpiar

Ahora vamos a ver de qué manera podemos transformar los datos para obtener respuestas a las siguientes preguntas:

- ¿cuáles son las palabras más frecuentes?

- ¿cuáles son las palabras con valoraciones más extremas?

- ¿cuáles son las palabras que se evocaron más rápido?

Para responder esto vamos a utilizar verbos de manipulación (de dplyr, una librería incluida en tidyverse) sobre nuestra tabla. Algunos de estos verbos son:

- filter() para filtrar los registos/observaciones por alguna condición de sus valores;

- mutate() para agregar una columna/variable con el resultado de alguna operación sobre otras columnas;

- group_by() y summarise() para realizar alguna operación sobre los datos de distintos registros, reduciendolos en uno sólo por grupos;

- n() que nos devuelve el conjunto de registros de un grupo (y que por ello se hace luego de group_by()); algo que podemos simplificar con count();

- arrange() ordena los datos ascendente o descendentemente;

Luego, para encadenar estas acciones vamos a utlizar un operador denominado pipe (%>%) que funciona como un tubo: toma el objeto a su izquierda y lo hace pasar por la función a su derecha, devolviendonos el resultado. Esto nos permite una manera más fácil de pensar a la hora de escribir el código para manipular un objeto, que su alternativa de incluir al objeto entre los paréntesis de una función, ya que en primer lugar lo mencionamos y luego iremos paso a paso introduciendole transformaciones.

Antes que nada, empecemos por chusmear (glimpse) la estructura de la base para recordar las columnas/variables con las que podemos trabajar. Los nombres de las columnas aparecen precedidos con un $, una debajo de la otra, para que sea más facil de observar tablas largas. Luego, nos informa el tipo de variable y nos permite ver los primeros valores (que en entran en pantalla)

Nuestra tabla tiene las palabras que los participantes respondieron en la columna

- asociaciones$palabra, el orden en que dichas palabras fueron ingresadas por el participante en asociaciones$orden, y una valoración sobre esa palabra expresada en forma númerica en asociaciones$valoracion.

Tenemos todos los elementos para responder las preguntas. Sólo falta diseñar un camino de operaciones para visibilizar la respuesta:

(Paso1) vamos a tomar la tabla que nos interesa asociaciones, y la vamos a pasar, para… (Paso2) …armar grupos de registros que compartan el valor en asociaciones$palabra, y para cada cual vamos a: (Paso3) contar la cantidad de registros (dandonos la frecuencia con que dicha palabra fue asociada a big data); (Paso4) y calcular la media de las valoraciones en asociaciones$valoracion , (Paso5) así como la media del orden en que fue evocado (asociaciones$orden) (Paso0) … el resultado de esta operación la vamos a guardar en una tabla nueva, que luego operaremos para responder nuestras 2 preguntas. En tanto esta tabla describe la información de la anterior, notaremos que tiene muchos menos registros.

Para estas operaciones vamos a usar los comandos recién vistos:

library(dplyr)

glimpse(asociaciones)
Rows: 1,707
Columns: 4
$ id         <chr> "-M0-9OQkabuGoSmceB5E", "-M0-9OQkabuGoSmceB5E", "-M0-9OQkab…
$ palabra    <chr> "información", "análisis", "investigación", "comercial", "f…
$ orden      <dbl> 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5,…
$ valoracion <dbl> 5, 5, 5, 4, -5, 5, 5, 5, 0, -3, 2, 4, 4, 3, 2, 5, 4, 0, 4, …
asoc_frecuentes <- asociaciones %>% # (Paso0) y (Paso1)

group_by(palabra) %>% # (Paso2)

summarize(

freq = n(), # (Paso3)

valoracion_media = mean(valoracion), # (Paso4)

orden_media = mean(orden) #(Paso5)

)

glimpse(asoc_frecuentes)
Rows: 867
Columns: 4
$ palabra          <chr> ".", "...", "0-1-2", "1984", "aa", "abiertos", "abund…
$ freq             <int> 3, 2, 1, 1, 1, 1, 1, 1, 1, 4, 5, 1, 1, 1, 1, 1, 1, 1,…
$ valoracion_media <dbl> 0.00, 0.00, 0.00, -5.00, 0.00, 3.00, 3.00, 5.00, 0.00…
$ orden_media      <dbl> 4.0, 4.5, 5.0, 2.0, 5.0, 2.0, 1.0, 2.0, 5.0, 2.5, 3.6…

Más sintéticamente podríamos usar tally() o count(). Recordá que podés obtener ayuda sobre estos comando ejecutando ? tally().

Si ordenamos esta tabla ya estamos en condiciones de indicar cuáles son las palabras más/menos frecuentes. Para esto vamos a usar slice_max(), que ordena los datos y los corta en alguna posición.

asoc_frecuentes %>% # no guardamos el resultado, solo lo imprimimos

slice_max(order_by = freq, n=10) # ordenamos por freq y cortamos en 10 registros
# A tibble: 10 × 4
   palabra       freq valoracion_media orden_media
   <chr>        <int>            <dbl>       <dbl>
 1 información    102             2.58        2.08
 2 datos           81             2.15        1.96
 3 control         35            -2.31        2.57
 4 internet        34             2.94        2.91
 5 tecnología      29             2.45        2.97
 6 informacion     28             2.29        2.54
 7 grande          20             2.7         2   
 8 análisis        19             3.11        2.89
 9 manipulación    18            -3.44        2.5 
10 conocimiento    16             4.44        2.75

La palabra más evocada fue “información”, junto con un conjunto de otras palabras que podemos decir que remiten al manejo de los datos mediados por la tecnología, con diversos productos, como puede ser el análisis de información y la generación de conocimiento, o la manipulación y el control (las únicas palabras que tienen una valoración negativa).

Para conocer las palabras más/menos valoradas deberemos generar otros cortes.

asoc_frecuentes %>%

slice_max(order_by = valoracion_media, n=10) # las de valor mas alto
# A tibble: 176 × 4
   palabra                             freq valoracion_media orden_media
   <chr>                              <int>            <dbl>       <dbl>
 1 abundante                              1                5           2
 2 accionar                               1                5           3
 3 actualizaciones                        1                5           3
 4 algo superior                          1                5           3
 5 almacenamiento de datos                2                5           2
 6 amigos                                 1                5           1
 7 amor                                   1                5           4
 8 amplitud de usos                       1                5           5
 9 análisis datos                         1                5           2
10 análisis de grandes masas de datos     1                5           1
# ℹ 166 more rows
asoc_frecuentes %>%

slice_min(order_by = valoracion_media, n=10) # las de valor mas bajo
# A tibble: 108 × 4
   palabra                freq valoracion_media orden_media
   <chr>                 <int>            <dbl>       <dbl>
 1 1984                      1               -5           2
 2 acción                    1               -5           4
 3 acoso mediático           1               -5           2
 4 altgorismo                1               -5           4
 5 atraso                    1               -5           4
 6 ausencia de intimidad     1               -5           4
 7 avismo                    1               -5           4
 8 buenas noticias           1               -5           3
 9 camdbridge analitycs      1               -5           2
10 campaña politica          1               -5           2
# ℹ 98 more rows

Más allá de que se puede inferir ciertos temas en las palabras (especialmente las negativas), nos debemos preguntar si tiene sentido trabajar con ideas y expresiones idiosincráticas, introducidos por un sólo participante. A fin de cuentas, la pregunta que guía toda nuestra exploración es sobre lso sentidos comunes o compartidos. Podemos entonces establecer un umbral o mínimo de repeticiones para que una palabra nos resulte relevante o informativa.

Miremos entonces las frecuencias. Otra vez, diseñemos un camino de operaciones:

(Paso1) vamos a tomar la tabla que nos interesa asoc_frecuentes, y la vamos a pasar, para… (Paso2) …armar grupos de registros que compartan el valor en asociaciones$freq, y para cada cual vamos a: (Paso3) contar la cantidad de registros (dandonos la cantidad de palabras que fueron dicha la misma cantidad de veces); (Paso4) vamos a visualizarlo en un gráfico de puntos que cruce la frecuencia y la cantidad de palabras.

Por su parte, el diseño del gráfico va a requerir 3 componentes (mínimos): que insertemos datos (en este caso, vamos a estar pasando la tabla hecha hasta el paso 3 con un pipe, de modo que no necesitamos declararla de nuevo), que mapeemos algunos de esos datos a propiedades visuales del gráfico (como por ejemplo, un cierta columna/variable para un eje del gráfico), y que elijamos un sistema de representación o “geometry” (puntos, barras, áreas, etc.)

library(ggplot2) # Carga la librería ggplot2

asoc_frecuentes %>% # Paso1

group_by(freq) %>% # Paso2

summarize(cant_palabras = n()) %>% # Paso3

ggplot( # Paso 4: usamos la librería ggplot2 y la función ggplot

aes(x=cant_palabras,y=freq) # mapeeamos los datos en los ejes x e y

) + # los componentes de ggplot se concatenan con +, ya que no son pasos secuenciales

geom_point()

Por lo visto, tenemos una distribución que sigue la ley de Zipf: muy poca cantidad de palabras tienen valores que se repiten muchas veces (los sentidos más comúnes), y hay casi 700 palabras que se repiten 1 sola vez. En vistas de esto podemos quedarnos con las palabras que se repiten más de 1 vez, criterio que utilizaremos para establecer un filtro (filter()). En esta ocasión, por simpleza, vamos a “pisar” nuestra tabla de datos con un fragmento de ella misma.

asoc_frecuentes <- asoc_frecuentes %>% # vamos a pisar la tabla con el resultado

filter(freq > 1)

glimpse(asoc_frecuentes)
Rows: 188
Columns: 4
$ palabra          <chr> ".", "...", "accesibilidad", "acceso", "algoritmos", …
$ freq             <int> 3, 2, 4, 5, 4, 7, 2, 2, 6, 19, 2, 2, 2, 3, 3, 2, 4, 1…
$ valoracion_media <dbl> 0.0000000, 0.0000000, 1.7500000, 0.6000000, 1.2500000…
$ orden_media      <dbl> 4.000000, 4.500000, 2.500000, 3.600000, 3.500000, 3.1…

Con este nuevo dataset deberíamos repetir los análisis anteriores sobre las palabras mas/menos valoradas. Este es un escenario al que deberemos acostrumbrarnos: el proceso de transformación-visualización-limpieza es iterativo. En la medida en que nos familiaricemos más con nuestros datos, que aclaremos nuestras preguntas, y que decidamos y programemos los análisis, deberemos repetirnos varias veces.

Por último, nos queda indagar cuáles son las palabras que más rápidamente fueron evocadas en la encuesta, es decir, las que tiene un orden de evocación más cercano a 1. Estas son las ideas que probablemente sean las más accesibles y memorables. Pero ahora en lugar de una lista, veamos un gráfico en el que podamos incluir otra información: la valoración media de la palabra.

asoc_frecuentes %>%

slice_min(order_by = orden_media, n=10) %>% # las de valor mas bajo

ggplot( # vamos a usar ggplot para graficar

aes( # dentro de aes indicamos las variables a vincular con las partes del gráfico

y = palabra, # en el eje y vamos a poner la palabra

x = orden_media, # en el eje x el orden de evocación

fill = valoracion_media # en el color vamos a poner la valoración (-5 y 5)

)

) +

geom_col()

Estos primeros análisis ya nos dan una idea de la estructura de los datos, y algunas pistas sobre las respuestas…

1.5.4 Funciones

analisis_proto <- function (tabla_evocaciones) {

# las operaciones van aca…

# por ahora no vamos a hacer nada mas que asignar nuestro input a un nuevo objeto…

objeto_a_devolver <- tabla_evocaciones

return(objeto_a_devolver) # … y lo devolvemos

}

Podemos llamar a la función con analisis_proto(asociaciones). Dada las operaciones que le definimos dentro, no nos debe sorprender que la función no haga más que llamar al objeto.

analisis_proto(asociaciones)
# A tibble: 1,707 × 4
   id                   palabra       orden valoracion
   <chr>                <chr>         <dbl>      <dbl>
 1 -M0-9OQkabuGoSmceB5E información       1          5
 2 -M0-9OQkabuGoSmceB5E análisis          2          5
 3 -M0-9OQkabuGoSmceB5E investigación     3          5
 4 -M0-9OQkabuGoSmceB5E comercial         4          4
 5 -M0-9OQkabuGoSmceB5E filtración        5         -5
 6 -M0U7_pJAU9Ehga0LIWq información       1          5
 7 -M0U7_pJAU9Ehga0LIWq tecnología        2          5
 8 -M0U7_pJAU9Ehga0LIWq sistemas          3          5
 9 -M0U7_pJAU9Ehga0LIWq computadora       4          0
10 -M0U7_pJAU9Ehga0LIWq freaks            5         -3
# ℹ 1,697 more rows

Es importante notar una cosa. Si prestamos atención al entorno, vamos a ver que el objeto_a_devolver no aparece en nuestra lista de objetos. Esto es porque quedó “encapsulado” en la función, y no está disponible por fuera de ella. Lo mismo puede decirse de tabla_evocaciones, que es la forma en que en la función llamamos a nuestro primer parámetro (los datos).

Aclarada la estructura y el uso de una función, ya sólo resta pensar en cuáles son los pasos a seguir para realizar el análiasis prototípico. Para eso, volvamos a la definición más arriba, y pensemos la secuencia de operaciones que necesitamos:

(paso 1) primero debemos calcular las frecuencias de cada palabra y sus medias de valoracion y orden; (paso 2) deberemos definir una frecuencia mínima; (paso 3) vamos a calcular los criterios de corte para distinguir los mas/menos frecuentes y los evocados mas/menos rápidamente; (paso 4) vamos a utilizar estos criterios de corte para segmentar las asociaciones, indicando qué palabras corresponden a qué segmento;

Como la idea es poder probar distintos criterios y decisiones, algunos de estos pasos suponen que podamos introducir algún parámetro: (paso 2) vamos a introducir una frecuencia mínima; (paso 3) vamos a indicar si queremos usar la media o la mediana para calcular el criterio de corte, es decir si aplicamos mean() o median(), esta operación condicional la haremos con una estructura de control: if ( criterio ) { … } else { … }. Estos 2 parámetros los vamos a incluir en la función, con un valor por defecto: 2 para la frecuencia mínima, y media para calcular el criterio. Vamos a utilizar el comando message() para que al correr la función se muestren estos parámetros, y también para observar la cantidad de palabras que quedan en cada segmento, dados estos parametros (paso 5).

analisis_proto <- function (tabla_evocaciones, frecuencia_minima = 2, criterio_corte = "media") {

# (paso 1) tabla de frecuencias

asoc_frecuentes <- tabla_evocaciones %>%

group_by(palabra) %>%

summarize(

freq = n(),

valoracion_media = mean(valoracion),

orden_media = mean(orden)

)

# (paso 2) establecemos un umbral de frecuencia minima (usando parametro)

asoc_frecuentes <- asoc_frecuentes %>%

filter(freq > frecuencia_minima)

message("frecuencia minima =", frecuencia_minima)

# (paso 3) calculamos el corte de frecuencia (usamos mean o median, segun parametro)

if (criterio_corte == "media") {

freq_cut <- mean(asoc_frecuentes$freq)

orden_cut <- mean(asoc_frecuentes$orden_media)

} else {

freq_cut <- median(asoc_frecuentes$freq)

orden_cut <- median(asoc_frecuentes$orden_media)

}

message("valor corte frecuencia =", freq_cut)

message("valor corte orden =", orden_cut)

# (paso 4) segmentamos las palabras

prototipico <- asoc_frecuentes %>% mutate( segmento = case_when(

freq >= freq_cut & orden_media < orden_cut ~ 1,

freq >= freq_cut & orden_media >= orden_cut ~ 2,

freq < freq_cut & orden_media < orden_cut ~ 3,

freq < freq_cut & orden_media >= orden_cut ~ 4

)

) %>% arrange(segmento, desc(freq),desc(orden_media))

# (paso 5) vamos a contar las palabras en cada segmento y lo mostramos en pantalla

palabras_por_segmento <- prototipico %>%

count(segmento) %>%

pull(n) # pull extrae una variable, quedando como vector

message("palabras en cada segmento =",

paste(palabras_por_segmento, collapse = " | "))

# … y lo devolvemos

return(prototipico)

}

Veamos el objeto que nos devuelve, por ahora con los valores por defecto:

analisis_proto(tabla_evocaciones = asociaciones)
frecuencia minima =2
valor corte frecuencia =8.15094339622642
valor corte orden =2.98106020168724
palabras en cada segmento =12 | 5 | 33 | 56
# A tibble: 106 × 5
   palabra       freq valoracion_media orden_media segmento
   <chr>        <int>            <dbl>       <dbl>    <dbl>
 1 información    102             2.58        2.08        1
 2 datos           81             2.15        1.96        1
 3 control         35            -2.31        2.57        1
 4 internet        34             2.94        2.91        1
 5 tecnología      29             2.45        2.97        1
 6 informacion     28             2.29        2.54        1
 7 grande          20             2.7         2           1
 8 análisis        19             3.11        2.89        1
 9 manipulación    18            -3.44        2.5         1
10 conocimiento    16             4.44        2.75        1
# ℹ 96 more rows

Ahora podemos probar otros parámetros

analisis_proto(tabla_evocaciones = asociaciones, frecuencia_minima = 3, criterio_corte = "mediana")
frecuencia minima =3
valor corte frecuencia =6
valor corte orden =3
palabras en cada segmento =23 | 18 | 9 | 24
# A tibble: 74 × 5
   palabra       freq valoracion_media orden_media segmento
   <chr>        <int>            <dbl>       <dbl>    <dbl>
 1 información    102             2.58        2.08        1
 2 datos           81             2.15        1.96        1
 3 control         35            -2.31        2.57        1
 4 internet        34             2.94        2.91        1
 5 tecnología      29             2.45        2.97        1
 6 informacion     28             2.29        2.54        1
 7 grande          20             2.7         2           1
 8 análisis        19             3.11        2.89        1
 9 manipulación    18            -3.44        2.5         1
10 conocimiento    16             4.44        2.75        1
# ℹ 64 more rows

Otra vez, es hora de tomar decisiones. Como vemos, esta última configuración logra quedarse con menos palabras, pero a la vez incrementa el tamaño del 1er segmento, que dado que es donde iremos a buscar los sentidos centrales, conviene que sea más pequeño. Podemos asumir que un umbral de frecuencia mínimas más alto, y una división por medias debería dar un conjnto más chico de palabras en el segmento 1, y menos palabras en total.

analisis_proto(tabla_evocaciones = asociaciones, frecuencia_minima = 5, criterio_corte = "media")
frecuencia minima =5
valor corte frecuencia =15.219512195122
valor corte orden =2.87623694419952
palabras en cada segmento =7 | 3 | 13 | 18
# A tibble: 41 × 5
   palabra       freq valoracion_media orden_media segmento
   <chr>        <int>            <dbl>       <dbl>    <dbl>
 1 información    102             2.58        2.08        1
 2 datos           81             2.15        1.96        1
 3 control         35            -2.31        2.57        1
 4 informacion     28             2.29        2.54        1
 5 grande          20             2.7         2           1
 6 manipulación    18            -3.44        2.5         1
 7 conocimiento    16             4.44        2.75        1
 8 internet        34             2.94        2.91        2
 9 tecnología      29             2.45        2.97        2
10 análisis        19             3.11        2.89        2
# ℹ 31 more rows

1.5.5 Interpretación

Siguiendo el análisis prototípico, nos interesan las asociaciones registradas con una frecuencia mayor y un rango por debajo de la media, es decir, las más frecuentes y salienten, ya que son las principales candidatas a expresar los sentidos más centrales y consensuados de la representación. En nuestra tabla serían aquellos registros con `segmento == 1`.

En Becerra and López-alurralde (2020) con un dataset muy similar a este sugeríamos:

El primer segmento comprende a las palabras enunciadas más frecuentemente y de más rápida evocación, es decir, las más comunes y accesibles. Estos son los términos que se puede decir que constituyen el núcleo de la representación: información, dato, internet, control, grande, bases de datos, manipulación, conocimiento, marketing, poder, computadora, espionaje, y grandes datos. Mayormente refieren a lo que denominamos la “premisa” del big data: la disponibilidad de grandes bases de datos, plausibles de otorgar información. Es interesante señalar que el término grande (lemma en el que convergen distintos términos, tales como grandes, mucho) es el único en el núcleo que remite a las famosas 3 V’s –volumen, velocidad y variedad– que popularizara Laney y que se referencia en prácticamente todas las noticias que buscan introducir al big data a un público masivo …

Mayormente estos términos están asociados con una valoración positiva, … siendo conocimiento la palabra de mayor valor medio … Sin embargo, también aparecen en este mismo segmento, las 3 palabras de menor valoración en todo el corpus: manipulación, espionaje y control. … La distribución de estas valoraciones es indicativa de la polaridad que recubre el campo semántico del big data, en tanto la imagen de la “gran oportunidad” que ofrece su promesa epistémica, convive con una retórica de sospecha frente a los riesgos de su explotación para el sometimiento y el condicionamiento de otros, como un “gran hermano”.

RS de “trabajo”

El cuadro está compuesto por 4 cuadrantes, resultante de ordenar las palabras por frecuencia y orden de evocación, ambas cortadas en 2 segmentos por el punto medio. La tabla es clara en segmentar palabras, aunque no hay manera fácil de identificar los segmentos si no es comparando frecuencias. Además, si quisierámos agregar una variable, como es valoración en nuestro caso, las tablas se vuelven extensas para compararlas.

Un gráfico debería debería permitirnos visualizar esto mejor!

Vamos a dibujar un gráfico que: permita dibujar puntos en el cruce de frecuencia (X) y orden de evocación (Y), * que incluya las palabras en el gráfico, de modo tal que podamos leerlas por grupitos, que señale con color la valoración, que muestre los puntos de corte en frecuencia (X) y orden de evocación (Y), y que remarque el cuadrante del núcleo central.

prototipico <- analisis_proto(tabla_evocaciones = asociaciones, frecuencia_minima = 5, criterio_corte = "media")
frecuencia minima =5
valor corte frecuencia =15.219512195122
valor corte orden =2.87623694419952
palabras en cada segmento =7 | 3 | 13 | 18
glimpse(prototipico)
Rows: 41
Columns: 5
$ palabra          <chr> "información", "datos", "control", "informacion", "gr…
$ freq             <int> 102, 81, 35, 28, 20, 18, 16, 34, 29, 19, 15, 10, 8, 8…
$ valoracion_media <dbl> 2.5784314, 2.1481481, -2.3142857, 2.2857143, 2.700000…
$ orden_media      <dbl> 2.078431, 1.962963, 2.571429, 2.535714, 2.000000, 2.5…
$ segmento         <dbl> 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,…
prototipico %>%

ggplot(aes(x=freq,y=orden_media,label=palabra)) + # frecuencia x orden

scale_x_continuous(trans='log') + # vamos a aplicar una transformación al eje X para ver mejor los puntos

geom_hline(yintercept = 2.87623694419952, linetype = 2) + # tomamos este valor del mensaje de la función

geom_vline(xintercept = 15.219512195122, linetype = 2) + # tomamos este valor del mensaje de la función

geom_point(aes(size=freq, colour=valoracion_media), show.legend = TRUE) + # agregamos los puntos

scale_colour_gradient(low = "red", high = "green", na.value = NA) + # gama de colores para valores continuos

geom_text( aes(size=20, colour=valoracion_media), fontface = "bold",

show.legend = FALSE, nudge_y = -.1, check_overlap = TRUE) + # agregamos las palabras

labs(y="Orden de evocación", x = "Frecuencia (log)") + # ponemos labels en los ejes

theme_minimal() # borremos estilos innecesarios

1.6 Importación de datos

  • CSV o archivos de texto plano: Puedes usar la función `read.csv()` para importar datos desde un archivo CSV. Por ejemplo:
datos <- read.csv("C:/Users/PC/Desktop/PLE/2/StudentsPerformance.csv", check.names = FALSE)
head(datos)
  g\xe9nero,"raza/etnia","nivel educativo de los padres","almuerzo","curso de preparaci\xf3n para el examen","puntuaci\xf3n en matem\xe1ticas","puntuaci\xf3n en lectura","puntuaci\xf3n en escritura"
1                                                                                                                                female,"group B","bachelor's degree","standard","none","72","72","74"
2                                                                                                                                female,"group C","some college","standard","completed","69","90","88"
3                                                                                                                                  female,"group B","master's degree","standard","none","90","95","93"
4                                                                                                                             male,"group A","associate's degree","free/reduced","none","47","57","44"
5                                                                                                                                       male,"group C","some college","standard","none","76","78","75"
6                                                                                                                               female,"group B","associate's degree","standard","none","71","83","78"
summary(datos)
     g\xe9nero,"raza/etnia","nivel educativo de los padres","almuerzo","curso de preparaci\xf3n para el examen","puntuaci\xf3n en matem\xe1ticas","puntuaci\xf3n en lectura","puntuaci\xf3n en escritura"
 Length:1000                                                                                                                                                                                             
 Class :character                                                                                                                                                                                        
 Mode  :character                                                                                                                                                                                        
  • En excel
library(readxl)

datos_excel <- read_excel("C:/Users/PC/Desktop/PLE/HLTH1025_2016.xlsx")
New names:
• `` -> `...2`
• `` -> `...3`
• `` -> `...4`
head(datos_excel)
# A tibble: 6 × 4
  `Health & Society Student Health Survey Metadata` ...2             ...3  ...4 
  <chr>                                             <chr>            <chr> <chr>
1 <NA>                                              <NA>             <NA>  <NA> 
2 Variable name                                     Variable label   Vari… Valu…
3 ID                                                Participant ide… Cont… <NA> 
4 sex                                               What is your ge… Cate… 1: M…
5 <NA>                                              <NA>             <NA>  2: F…
6 <NA>                                              <NA>             <NA>  99: …
summary(datos_excel)
 Health & Society Student Health Survey Metadata     ...2          
 Length:205                                      Length:205        
 Class :character                                Class :character  
 Mode  :character                                Mode  :character  
     ...3               ...4          
 Length:205         Length:205        
 Class :character   Class :character  
 Mode  :character   Mode  :character  
  • Importar archci stata
library(haven)

datos_stata <- read_dta("C:/Users/PC/Desktop/PLE/auto.dta")
head(datos_stata)
# A tibble: 6 × 12
  make         price   mpg rep78 headroom trunk weight length  turn displacement
  <chr>        <dbl> <dbl> <dbl>    <dbl> <dbl>  <dbl>  <dbl> <dbl>        <dbl>
1 AMC Concord   4099    22     3      2.5    11   2930    186    40          121
2 AMC Pacer     4749    17     3      3      11   3350    173    40          258
3 AMC Spirit    3799    22    NA      3      12   2640    168    35          121
4 Buick Centu…  4816    20     3      4.5    16   3250    196    40          196
5 Buick Elect…  7827    15     4      4      20   4080    222    43          350
6 Buick LeSab…  5788    18     3      4      21   3670    218    43          231
# ℹ 2 more variables: gear_ratio <dbl>, foreign <dbl+lbl>
summary(datos_stata)
     make               price            mpg            rep78      
 Length:74          Min.   : 3291   Min.   :12.00   Min.   :1.000  
 Class :character   1st Qu.: 4220   1st Qu.:18.00   1st Qu.:3.000  
 Mode  :character   Median : 5006   Median :20.00   Median :3.000  
                    Mean   : 6165   Mean   :21.30   Mean   :3.406  
                    3rd Qu.: 6332   3rd Qu.:24.75   3rd Qu.:4.000  
                    Max.   :15906   Max.   :41.00   Max.   :5.000  
                                                    NA's   :5      
    headroom         trunk           weight         length           turn      
 Min.   :1.500   Min.   : 5.00   Min.   :1760   Min.   :142.0   Min.   :31.00  
 1st Qu.:2.500   1st Qu.:10.25   1st Qu.:2250   1st Qu.:170.0   1st Qu.:36.00  
 Median :3.000   Median :14.00   Median :3190   Median :192.5   Median :40.00  
 Mean   :2.993   Mean   :13.76   Mean   :3019   Mean   :187.9   Mean   :39.65  
 3rd Qu.:3.500   3rd Qu.:16.75   3rd Qu.:3600   3rd Qu.:203.8   3rd Qu.:43.00  
 Max.   :5.000   Max.   :23.00   Max.   :4840   Max.   :233.0   Max.   :51.00  
                                                                               
  displacement     gear_ratio       foreign      
 Min.   : 79.0   Min.   :2.190   Min.   :0.0000  
 1st Qu.:119.0   1st Qu.:2.730   1st Qu.:0.0000  
 Median :196.0   Median :2.955   Median :0.0000  
 Mean   :197.3   Mean   :3.015   Mean   :0.2973  
 3rd Qu.:245.2   3rd Qu.:3.353   3rd Qu.:1.0000  
 Max.   :425.0   Max.   :3.890   Max.   :1.0000  
                                                 
  • Importarten formato
datos_tsv <- read.delim("C:/Users/PC/Desktop/PLE/sample-1.tsv")
head(datos_tsv)
   X     X.1 X.2 X.3 X.4 X.5 X.6 X.7 X.8      X.9 X.10 X.11 X.12 X.13 X.14 X.15
1 NA JANUARY                          NA FEBRUARY                              
2 NA       S   M   T   W   T   F   S  NA        S    M    T    W    T    F    S
3 NA                               1  NA                  1    2    3    4    5
4 NA       2   3   4   5   6   7   8  NA        6    7    8    9   10   11   12
5 NA       9  10  11  12  13  14  15  NA       13   14   15   16   17   18   19
6 NA      16  17  18  19  20  21  22  NA       20   21   22   23   24   25   26
  X.16  X.17 X.18 X.19 X.20 X.21 X.22 X.23 X.24 X2022
1   NA MARCH                                 NA    NA
2   NA     S    M    T    W    T    F    S   NA    NA
3   NA               1    2    3    4    5   NA    NA
4   NA     6    7    8    9   10   11   12   NA    NA
5   NA    13   14   15   16   17   18   19   NA    NA
6   NA    20   21   22   23   24   25   26   NA    NA
  Create.more.with.themes..............Go.to..Format.....Theme
1                                                           NA
2                                                           NA
3                                                           NA
4                                                           NA
5                                                           NA
6                                                           NA
summary(datos_tsv)
    X               X.1                X.2                X.3           
 Mode:logical   Length:35          Length:35          Length:35         
 NA's:35        Class :character   Class :character   Class :character  
                Mode  :character   Mode  :character   Mode  :character  
     X.4                X.5                X.6                X.7           
 Length:35          Length:35          Length:35          Length:35         
 Class :character   Class :character   Class :character   Class :character  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character  
   X.8              X.9                X.10               X.11          
 Mode:logical   Length:35          Length:35          Length:35         
 NA's:35        Class :character   Class :character   Class :character  
                Mode  :character   Mode  :character   Mode  :character  
     X.12               X.13               X.14               X.15          
 Length:35          Length:35          Length:35          Length:35         
 Class :character   Class :character   Class :character   Class :character  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character  
   X.16             X.17               X.18               X.19          
 Mode:logical   Length:35          Length:35          Length:35         
 NA's:35        Class :character   Class :character   Class :character  
                Mode  :character   Mode  :character   Mode  :character  
     X.20               X.21               X.22               X.23          
 Length:35          Length:35          Length:35          Length:35         
 Class :character   Class :character   Class :character   Class :character  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character  
   X.24          X2022        
 Mode:logical   Mode:logical  
 NA's:35        NA's:35       
                              
 Create.more.with.themes..............Go.to..Format.....Theme
 Mode:logical                                                
 NA's:35