5 Tablas especiales

En esta sección nos introducimos en algunas de las características que hacen muy especial a este paquete expss. Iremos introduciendo cada uno de los conceptos en el punto donde corresponda, dando la explicación de caso de uso, más que su explicación técnica. El usuario que quiera conocer más sobre ello, puede acudir a la guía de referencia de todas las opciones de este paquete.

Aprenderemos a usar:

  • tab_subgroup(), que permite hacer la tabla con una parte de los datos;
  • %nest%, que permite anidar variables;
  • total_row_label(), escribir textos libres en filas en la secuencia que se indique;
  • recode(), recodificar en línea una variable (ver 6.2 );
  • var_lab(), modificar o asignar el texto de la variable;
  • val_lab(), modificar o asignar los textos de los códigos;
  • drop_rc(), borrar columnas o filas [drop_empty_rows() y drop_empty_cols()];
  • tab_sort_asc(), para ordenar ascendente o descendente tab_sort_desc();
  • uso de na_if, para eliminar valores de niveles que no se desean computar en el cálculo de estadísticos;
  • uso de criterios, para establecer sencillos mecanismos de filtro como complemento a otras funciones.

5.1 Subgrupos (filtros en la tabla)

Una de las primeras cuestiones que nos surge en muchas ocasiones es trabajar con subgrupos de la información original, bien porque deseamos una tabla de sólo un parte de la muestra o bien porque buscamos comparar determinados elementos en una misma tabla. Veamos las posibilidades y las situaciones de uso.

En la siguiente tabla, filtramos el banco de datos para aquellos entrevistados que han declarado tener hijos (P34 == 1) por un lado y los que no por otro (P34 == 2). Para ello usamos la instrucción tab_subgroup() e introducimos también la instrucción tab_row_label() donde escribimos una fila con texto libre. Puedes consultar en la sección 10 como se escriben las condiciones y cuáles son los operadores que puede utilizar expss, que su vez, tiene algunos operadores propios que en esta misma sección incluiremos.

as.datatable_widget(data %>%
    tab_subgroup(P34 == 1) %>%
    tab_row_label("Entrevistado con hijos") %>%
    tab_cols(total(), P31) %>%
    tab_cells(P36) %>%
    tab_stat_cases() %>%
    tab_subgroup(P34 == 2) %>%
    tab_row_label("Entrevistado sin hijos") %>%
    tab_cols(total(), P31) %>%
    tab_cells(P36) %>%
    tab_stat_cases() %>%
    tab_pivot())

Figura 5.1: Tabla con subgrupos

5.2 Bases y/o con anidación

El concepto de base, no está contemplado como tal en expss, pero podemos utilizar las diferentes combinaciones de instrucciones para poder obtener el resultado deseado. Por ejemplo, si queremos trabajar con bases de la variable P34 (entrevistado tiene hijos o no tiene hijos), y obtener réplica de la tabla para ambas categorías, lo podíamos hacer de la forma anterior, pero hay otra posibilidad y es utilizar la opción de añadir variables anidadas en filas o utilizar de forma simultánea las instrucciones tab_rows() y tab_cells().

En esta tabla hay algunas cosas a reseñar.

  • En primer lugar P34 == 1 | P34 == 2 es la condición de los casos con los que deseamos trabajar. No queremos contemplar los No Contesta. Se podría hacer también con el na_if() que veremos más adelante, pero creemos más clara esta opción.
  • Por otro lado, usamos tab_cols(), tab_rows() y tab_cells() lo que nos va a dar una publicación curiosa que responde a nuestra necesidad.
  • Por último, los códigos de P34, redefinidos al principio del script, se muestran como en una primera columna, diferenciados claramente del resto. La variable en tab_cells() de la que se calcula el estadístico (número de casos) se muestra como en una segunda columna, aunque realmente en el dataframe es sólo una. Hemos dejado fuera la opción de No Contesta aunque ya anticipamos que no tenía ningún caso.

La función var_lab() permite asignar a una variable (data$P34) una lista (expresa con la función base de R denominada vector c() vector) de etiquetas donde el texto de la etiqueta va entrecomillado y el valor va igualado a la etiqueta. Es una forma muy simple, a la par que práctica, de etiquetar los valores de una variable.

val_lab(data$P34) <- c("Sí" = 1, "No" = 2)  # los valores de P34 son etiquetados como ...
as.datatable_widget(data %>%
    tab_subgroup(P34 == 1 | P34 == 2) %>%
    tab_cols(total(), P31) %>%
    tab_rows(P34) %>%
    tab_cells(P36) %>%
    tab_stat_cases() %>%
    tab_pivot())

Figura 5.2: Tabla con bases 1

Si nos gusta esta opción, se le puede añadir un modificador llamado %nest% que nos va a permitir anidar esas bases de cálculo. El modificador %nest% nos permite anidar los niveles o categorías de las variables. Cualquiera de las tablas anteriores puede ser anidada en tantos niveles como se desee con la opción %nest%. Para que la tabla no se alargue horizontalmente, reasignamos el texto extra de la variable denominada P3bis. Usamos también el recode()para dejar tan sólo tres niveles en la variable P3. Más adelante en la sección 6.2 una mayor profundidad con el recode().

data$P3bis <- recode(data$P3, 0:5 ~1, 6:10 ~2)
var_lab(data$P3bis) <- "Satisfacción"
val_lab(data$P3bis) <- c("1.Negativa" = 1, "2.Positiva" = 2)
val_lab(data$P34) <- c("1.Sí" = 1, "2.No" = 2)
as.datatable_widget(data %>%
    tab_subgroup(P34 == 1 | P34 == 2) %>%
    tab_cols(total(), P31) %>%
    tab_rows(P3bis %nest% P34) %>%
    tab_cells(P36) %>%
    tab_stat_cases(total_row_position = "none") %>%
    tab_pivot()) 

Figura 5.3: Tabla con bases 2

Algo más, si añadimos la instrucción drop_rc(), nótese la diferencia, pues desaparecen las filas y columnas sin información.

data$P3bis <- recode(data$P3, 0:5 ~1, 6:10 ~2)
var_lab(data$P3bis) <- "Satisfacción"
val_lab(data$P3bis) <- c("1.Negativa" = 1, "2.Positiva" = 2)
val_lab(data$P34) <- c("1.Sí" = 1, "2.No" = 2)
as.datatable_widget(data %>%
    tab_subgroup(P34 == 1 | P34 == 2) %>%
    tab_cols(total(), P31) %>%
    tab_rows(P3bis %nest% P34) %>%
    tab_cells(P36) %>%
    tab_stat_cases(total_row_position = "none") %>%
    tab_pivot() %>% 
    drop_rc())

Figura 5.4: Borrando filas y columnas vacías

5.3 Características avanzadas

Hagamos ahora lo mismo, pero combinando con un cálculo estadístico, por ejemplo nuevamente la media de P6C (atención recibida en consultas). Fijémonos en la nueva aportación realizada. En el tab_cells(), se le está indicando que se trabaje con la variable P6C, pero que considere NA (valores nulos) todos aquello que sean mayores que 5. ¿Por qué? porque los valores 8 y 9, han sido asignados al no sabe y no contesta respectivamente, y no queremos que entren en la media. Esto lo hacemos usando la función na_if().

Los criterios más básicos son:

  • igual -> equals, eq
  • no igual -> not_equals, neq, ne
  • mayor que -> greater, gt
  • mayor o igual que -> greater_or_equal, gte, ge
  • menor que -> less, lt
  • menor o igual que -> less_or_equal, lte, le

Puede usarse la expresión larga o también cualquiera de las cortas. Por tanto, na_if(P6C, gt(5)) significa trabaja con la variable P6C considerando NA los valores mayores que 5.

var_lab(data$P6C) <- "Valoración de la atención recibida"
data$P3bis <- recode(data$P3, 0:5 ~1, 6:10 ~2)
val_lab(data$P3bis) <- c("Negativa" = 1, "Positiva" = 2)
val_lab(data$P34) <- c("Sí" = 1, "No" = 2)
as.datatable_widget(data %>%
    tab_subgroup(P34 == 1 | P34 == 2) %>%
    tab_cols(total(), P31) %>%
    tab_rows(P3bis %nest% P34) %>%
    tab_cells(P6C= na_if(P6C, gt(5))) %>%
    tab_stat_mean() %>%
    tab_pivot())

Figura 5.5: Usando criterios

Se puede anidar también en filas y columnas. Vamos a reducir a dos el nivel de anidación para que se lea bien la tabla.

data$P3bis <- recode(data$P3, 0:5 ~1, 6:10 ~2)
var_lab(data$P3bis) <- "Satisfacción"
val_lab(data$P3bis) <- c("1.Negativa" = 1, "2.Positiva" = 2)
val_lab(data$P34) <- c("1.Sí" = 1, "2.No" = 2)
as.datatable_widget(data %>%
    tab_cols(P31 %nest% P34) %>% 
    tab_rows(P3bis %nest% P33) %>%
    tab_stat_cases(total_row_position="none") %>%
    tab_pivot())

Figura 5.6: Anidando filas y columnas

Como caso particular en muchos casos se requieren los subtotales de los niveles de anidación. Fíjate esta tabla y trata de ver las diferencias con la anterior.

as.datatable_widget(data %>%
    tab_cols(P31 %nest%  list(total(),P34)) %>% 
    tab_rows(P36 %nest% P33) %>%
    tab_stat_cases() %>%
    tab_sort_desc() %>%
    tab_pivot())

Figura 5.7: Anidando con subtotales

Efectivamente, han aparecido más columnas porque hemos anidado la columna de totales a la primera variable en lugar de usar el campo, hemos usado una lista de campos y además hemos ordenado de forma descendente respecto de la columna de total.

Pues hasta aquí una nueva sección completada. Continuamos en la sección 6 incluyendo otras características de apoyo