Utilizaremos las funciones 'gather()' 'spread()' y 'separate()' del paquete 'Tidyr' de R. Por medio de estas funciones podemos pasar varias variables que se encuentran en columnas separadas a una única variable y al revés. Además, podemos añadir nuevas columnas con variables que se encontraban agrupadas en una única variable. De paso haremos algunas representaciones de datos con ggplot2 de series temporales.
Nuestra matriz de datos presenta tres tratamientos diferentes aplicados a varios individuos. Con el paso del tiempo se ha valorado la capacidad de atención de cada individuo (estudiante) sobre 10. Vamos a cargar los datos para ver como son:
setwd(dir = "F:/R/MARKDOWN/manejomatrices/")
datos<-read.table("nuestrosdatos.csv", sep = ";", header = TRUE, dec = ".")
datos
## Individuo Tratamiento t1 t2 t3 t4 t5 t6
## 1 1 1 9.0 8.50 6.50 5.0 9.80 9.5
## 2 2 1 8.0 8.75 3.60 4.5 8.00 9.0
## 3 3 1 9.0 8.50 4.75 5.0 8.50 8.0
## 4 4 1 7.0 6.70 4.80 5.2 6.90 7.5
## 5 5 2 8.0 9.00 5.50 4.0 2.00 2.5
## 6 6 2 6.5 7.00 5.60 3.5 6.00 5.5
## 7 7 2 9.2 8.75 5.90 4.0 6.00 5.0
## 8 8 2 10.0 9.90 8.10 4.2 5.00 5.0
## 9 9 3 8.5 4.00 5.50 4.1 1.20 1.0
## 10 10 3 7.5 8.00 8.70 3.5 0.50 1.5
## 11 11 3 9.8 8.50 8.00 3.0 0.50 1.0
## 12 12 3 9.8 8.50 8.00 4.0 0.75 1.5
str(datos)
## 'data.frame': 12 obs. of 8 variables:
## $ Individuo : int 1 2 3 4 5 6 7 8 9 10 ...
## $ Tratamiento: int 1 1 1 1 2 2 2 2 3 3 ...
## $ t1 : num 9 8 9 7 8 6.5 9.2 10 8.5 7.5 ...
## $ t2 : num 8.5 8.75 8.5 6.7 9 7 8.75 9.9 4 8 ...
## $ t3 : num 6.5 3.6 4.75 4.8 5.5 5.6 5.9 8.1 5.5 8.7 ...
## $ t4 : num 5 4.5 5 5.2 4 3.5 4 4.2 4.1 3.5 ...
## $ t5 : num 9.8 8 8.5 6.9 2 6 6 5 1.2 0.5 ...
## $ t6 : num 9.5 9 8 7.5 2.5 5.5 5 5 1 1.5 ...
Vamos a comprobar si tenemos valores perdidos y la distribución de los datos de una forma sencilla (hay muchas más herramientas en los paquetes indicados):
library(pastecs)
library(summarytools)
## Registered S3 method overwritten by 'pryr':
## method from
## print.bytes Rcpp
## For best results, restart R session and update pander using devtools:: or remotes::install_github('rapporter/pander')
library(DataExplorer)
library(Rmisc)
## Loading required package: lattice
## Loading required package: plyr
#Si hay datos perdidos
plot_missing(datos)
plot_histogram(datos)
plot_density(datos)
No encontramos datos perdidos y las distribuciones son muy variadas, pero hay que tener en cuenta que el número de observaciones es bajo.
Vamos a cambiar todos los tiempos a una única columna que será el grado de atención. Para ello se utiliza 'gather' del paquete 'tidyr':
library("tidyr")
##
## Attaching package: 'tidyr'
## The following object is masked from 'package:pastecs':
##
## extract
#con la función 'gather' vamos a mover una serie de columnas a una única columna
datos2 <- gather(datos,
key = "Time",#nombre para la variable resultante de transponer todas las columnas de los diferentes tiempos (t1, t2, t3, etc.)
value = "Grado_de_atencion",#variable que estamos agrupando y el nombre que tendrá la nueva columna
t1:t6)#desde que columna hasta que columna queremos transponer
datos2
## Individuo Tratamiento Time Grado_de_atencion
## 1 1 1 t1 9.00
## 2 2 1 t1 8.00
## 3 3 1 t1 9.00
## 4 4 1 t1 7.00
## 5 5 2 t1 8.00
## 6 6 2 t1 6.50
## 7 7 2 t1 9.20
## 8 8 2 t1 10.00
## 9 9 3 t1 8.50
## 10 10 3 t1 7.50
## 11 11 3 t1 9.80
## 12 12 3 t1 9.80
## 13 1 1 t2 8.50
## 14 2 1 t2 8.75
## 15 3 1 t2 8.50
## 16 4 1 t2 6.70
## 17 5 2 t2 9.00
## 18 6 2 t2 7.00
## 19 7 2 t2 8.75
## 20 8 2 t2 9.90
## 21 9 3 t2 4.00
## 22 10 3 t2 8.00
## 23 11 3 t2 8.50
## 24 12 3 t2 8.50
## 25 1 1 t3 6.50
## 26 2 1 t3 3.60
## 27 3 1 t3 4.75
## 28 4 1 t3 4.80
## 29 5 2 t3 5.50
## 30 6 2 t3 5.60
## 31 7 2 t3 5.90
## 32 8 2 t3 8.10
## 33 9 3 t3 5.50
## 34 10 3 t3 8.70
## 35 11 3 t3 8.00
## 36 12 3 t3 8.00
## 37 1 1 t4 5.00
## 38 2 1 t4 4.50
## 39 3 1 t4 5.00
## 40 4 1 t4 5.20
## 41 5 2 t4 4.00
## 42 6 2 t4 3.50
## 43 7 2 t4 4.00
## 44 8 2 t4 4.20
## 45 9 3 t4 4.10
## 46 10 3 t4 3.50
## 47 11 3 t4 3.00
## 48 12 3 t4 4.00
## 49 1 1 t5 9.80
## 50 2 1 t5 8.00
## 51 3 1 t5 8.50
## 52 4 1 t5 6.90
## 53 5 2 t5 2.00
## 54 6 2 t5 6.00
## 55 7 2 t5 6.00
## 56 8 2 t5 5.00
## 57 9 3 t5 1.20
## 58 10 3 t5 0.50
## 59 11 3 t5 0.50
## 60 12 3 t5 0.75
## 61 1 1 t6 9.50
## 62 2 1 t6 9.00
## 63 3 1 t6 8.00
## 64 4 1 t6 7.50
## 65 5 2 t6 2.50
## 66 6 2 t6 5.50
## 67 7 2 t6 5.00
## 68 8 2 t6 5.00
## 69 9 3 t6 1.00
## 70 10 3 t6 1.50
## 71 11 3 t6 1.00
## 72 12 3 t6 1.50
Vamos a incluir el grado de atención en porcentaje. Para ello hay que multiplicar 'Grado_de_atención" por 10 y generar una nueva variable de la siguiente forma:
datos2$Grado_porcentaje<-(datos2$Grado_de_atencion*10)
datos2
## Individuo Tratamiento Time Grado_de_atencion Grado_porcentaje
## 1 1 1 t1 9.00 90.0
## 2 2 1 t1 8.00 80.0
## 3 3 1 t1 9.00 90.0
## 4 4 1 t1 7.00 70.0
## 5 5 2 t1 8.00 80.0
## 6 6 2 t1 6.50 65.0
## 7 7 2 t1 9.20 92.0
## 8 8 2 t1 10.00 100.0
## 9 9 3 t1 8.50 85.0
## 10 10 3 t1 7.50 75.0
## 11 11 3 t1 9.80 98.0
## 12 12 3 t1 9.80 98.0
## 13 1 1 t2 8.50 85.0
## 14 2 1 t2 8.75 87.5
## 15 3 1 t2 8.50 85.0
## 16 4 1 t2 6.70 67.0
## 17 5 2 t2 9.00 90.0
## 18 6 2 t2 7.00 70.0
## 19 7 2 t2 8.75 87.5
## 20 8 2 t2 9.90 99.0
## 21 9 3 t2 4.00 40.0
## 22 10 3 t2 8.00 80.0
## 23 11 3 t2 8.50 85.0
## 24 12 3 t2 8.50 85.0
## 25 1 1 t3 6.50 65.0
## 26 2 1 t3 3.60 36.0
## 27 3 1 t3 4.75 47.5
## 28 4 1 t3 4.80 48.0
## 29 5 2 t3 5.50 55.0
## 30 6 2 t3 5.60 56.0
## 31 7 2 t3 5.90 59.0
## 32 8 2 t3 8.10 81.0
## 33 9 3 t3 5.50 55.0
## 34 10 3 t3 8.70 87.0
## 35 11 3 t3 8.00 80.0
## 36 12 3 t3 8.00 80.0
## 37 1 1 t4 5.00 50.0
## 38 2 1 t4 4.50 45.0
## 39 3 1 t4 5.00 50.0
## 40 4 1 t4 5.20 52.0
## 41 5 2 t4 4.00 40.0
## 42 6 2 t4 3.50 35.0
## 43 7 2 t4 4.00 40.0
## 44 8 2 t4 4.20 42.0
## 45 9 3 t4 4.10 41.0
## 46 10 3 t4 3.50 35.0
## 47 11 3 t4 3.00 30.0
## 48 12 3 t4 4.00 40.0
## 49 1 1 t5 9.80 98.0
## 50 2 1 t5 8.00 80.0
## 51 3 1 t5 8.50 85.0
## 52 4 1 t5 6.90 69.0
## 53 5 2 t5 2.00 20.0
## 54 6 2 t5 6.00 60.0
## 55 7 2 t5 6.00 60.0
## 56 8 2 t5 5.00 50.0
## 57 9 3 t5 1.20 12.0
## 58 10 3 t5 0.50 5.0
## 59 11 3 t5 0.50 5.0
## 60 12 3 t5 0.75 7.5
## 61 1 1 t6 9.50 95.0
## 62 2 1 t6 9.00 90.0
## 63 3 1 t6 8.00 80.0
## 64 4 1 t6 7.50 75.0
## 65 5 2 t6 2.50 25.0
## 66 6 2 t6 5.50 55.0
## 67 7 2 t6 5.00 50.0
## 68 8 2 t6 5.00 50.0
## 69 9 3 t6 1.00 10.0
## 70 10 3 t6 1.50 15.0
## 71 11 3 t6 1.00 10.0
## 72 12 3 t6 1.50 15.0
Ahora ya tenemos todo listo para poder manejar la nueva matriz y preparar las figuras para ver como son nuestros resultados.
Vamos a representar nuestros datos. El primer paso es calcular lo que queremos representar en la figura de ggplot2.
Cargamos 'Rmisc' y transformamos en factor el tiempo y el tratamiento:
library(Rmisc)
datos2$Tratamiento<-factor(datos2$Tratamiento)#tratamiento como factor
datos2$Time<-factor(datos2$Time)#tiempo como factor
str(datos2)
## 'data.frame': 72 obs. of 5 variables:
## $ Individuo : int 1 2 3 4 5 6 7 8 9 10 ...
## $ Tratamiento : Factor w/ 3 levels "1","2","3": 1 1 1 1 2 2 2 2 3 3 ...
## $ Time : Factor w/ 6 levels "t1","t2","t3",..: 1 1 1 1 1 1 1 1 1 1 ...
## $ Grado_de_atencion: num 9 8 9 7 8 6.5 9.2 10 8.5 7.5 ...
## $ Grado_porcentaje : num 90 80 90 70 80 65 92 100 85 75 ...
Lo siguiente es calcular los valores medios y medidas de desviación para nuestros datos. Con 'measurevar' indicamos la variable que vamos a utilizar para los cálculos y con 'groupvars' los criterios de agrupación (tiempo y tratamiento):
nuevos <- summarySE(datos2, measurevar="Grado_porcentaje", groupvars=c("Time","Tratamiento"))
nuevos
## Time Tratamiento N Grado_porcentaje sd se ci
## 1 t1 1 4 82.500 9.574271 4.787136 15.234802
## 2 t1 2 4 84.250 15.239751 7.619875 24.249844
## 3 t1 3 4 89.000 11.165423 5.582711 17.766679
## 4 t2 1 4 81.125 9.490126 4.745063 15.100909
## 5 t2 2 4 86.625 12.133803 6.066901 19.307588
## 6 t2 3 4 72.500 21.794495 10.897247 34.679905
## 7 t3 1 4 49.125 11.946931 5.973466 19.010234
## 8 t3 2 4 62.750 12.284814 6.142407 19.547881
## 9 t3 3 4 75.500 14.059398 7.029699 22.371639
## 10 t4 1 4 49.250 2.986079 1.493039 4.751518
## 11 t4 2 4 39.250 2.986079 1.493039 4.751518
## 12 t4 3 4 36.500 5.066228 2.533114 8.061499
## 13 t5 1 4 83.000 12.027746 6.013873 19.138827
## 14 t5 2 4 47.500 18.929694 9.464847 30.121368
## 15 t5 3 4 7.375 3.300884 1.650442 5.252443
## 16 t6 1 4 85.000 9.128709 4.564355 14.525814
## 17 t6 2 4 45.000 13.540064 6.770032 21.545263
## 18 t6 3 4 12.500 2.886751 1.443376 4.593466
str(nuevos)
## 'data.frame': 18 obs. of 7 variables:
## $ Time : Factor w/ 6 levels "t1","t2","t3",..: 1 1 1 2 2 2 3 3 3 4 ...
## $ Tratamiento : Factor w/ 3 levels "1","2","3": 1 2 3 1 2 3 1 2 3 1 ...
## $ N : num 4 4 4 4 4 4 4 4 4 4 ...
## $ Grado_porcentaje: num 82.5 84.2 89 81.1 86.6 ...
## $ sd : num 9.57 15.24 11.17 9.49 12.13 ...
## $ se : num 4.79 7.62 5.58 4.75 6.07 ...
## $ ci : num 15.2 24.2 17.8 15.1 19.3 ...
plot_missing(nuevos)#sin valores perdidos
La forma más sencilla de representar los datos. El tiempo en el eje x y la capacidad de atención en el eje y:
library(ggplot2)
gr1<-ggplot(nuevos, aes(Time, Grado_porcentaje,group=Tratamiento,colour=Tratamiento)) +
geom_point() +
xlab("Tiempo") +#rótulos eje x e y
ylab("Porcentaje de atención")
gr1
Le añadimos líneas:
gr2<-gr1+geom_line()
gr2
Utilizamos 'geom_errorbar' para incluir los errores que hemos calculado en los pasos anteriores:
gr3<-ggplot(nuevos, aes(x=Time, y=Grado_porcentaje,group=Tratamiento, colour=Tratamiento)) +
geom_errorbar(aes(ymin=Grado_porcentaje-se, ymax=Grado_porcentaje+se), width=.1) +
geom_point()+
xlab("Tiempo")+
ylab("Grado de atención")
gr3
Añadimos una linea vertical para indicar el descanso que hemos hecho en mitad de la clase. Con 'scale_x_discrete' y 'drop=FALSE' consigo que el eje X que es categórico pase a continuo y la línea se pueda poner entre dos tiempos diferentes:
gr4<-gr3 +geom_vline(xintercept = 3.5)+
scale_x_discrete(drop = FALSE)
gr4
Con 'facet_wrap' en función del '~Tratamiento' separamos en tres figuras y con 'labeller' le damos nombre a nuestros tratamientos:
gr5<-gr3+facet_wrap(~Tratamiento,labeller=as_labeller(c("1" = "Clase Magistral bien hecha", "2" = "Innovación docente regulera",
"3" = "Innovación docente mal hecha")))
gr5+geom_line()
Quitamos la leyenda:
gr6<-gr5+geom_line()+theme(legend.position = "none")
gr6
Mejoramos la figura con puntos más grandes:
gr7<-gr6+geom_point(size=3)+geom_line(size=1)
gr7
Ponemos los descansos a las tres figuras:
gr8<-gr7+geom_vline(xintercept = 3.5,linetype = "dashed")+
scale_x_discrete(drop = FALSE)
gr8
Mejoramos los nombres de los tratamientos y el tamaño de todas las fuentes de los ejes con 'strip.text':
gr9<-gr8+theme(strip.text = element_text(face = "bold", color = "black",
hjust = 0.5, size = 8),
strip.background = element_rect(fill = "grey"),text = element_text(size = 15))
gr9
Se puede cambiar el fondo de la figura:
gr9+theme_classic()+theme(legend.position = "none")
gr9+theme_light()+theme(legend.position = "none")
gr9+theme_dark()+theme(legend.position = "none")#etc.
Vamos a cambiar la matriz para dejarla como estaba al principio. Para ello se utiliza 'spread()' del paquete 'tidyr':
Lo primero es quitar la variable "Grado_de_atencion" ya que no la usaremos más:
datos2$Grado_de_atencion<-NULL
datos2
## Individuo Tratamiento Time Grado_porcentaje
## 1 1 1 t1 90.0
## 2 2 1 t1 80.0
## 3 3 1 t1 90.0
## 4 4 1 t1 70.0
## 5 5 2 t1 80.0
## 6 6 2 t1 65.0
## 7 7 2 t1 92.0
## 8 8 2 t1 100.0
## 9 9 3 t1 85.0
## 10 10 3 t1 75.0
## 11 11 3 t1 98.0
## 12 12 3 t1 98.0
## 13 1 1 t2 85.0
## 14 2 1 t2 87.5
## 15 3 1 t2 85.0
## 16 4 1 t2 67.0
## 17 5 2 t2 90.0
## 18 6 2 t2 70.0
## 19 7 2 t2 87.5
## 20 8 2 t2 99.0
## 21 9 3 t2 40.0
## 22 10 3 t2 80.0
## 23 11 3 t2 85.0
## 24 12 3 t2 85.0
## 25 1 1 t3 65.0
## 26 2 1 t3 36.0
## 27 3 1 t3 47.5
## 28 4 1 t3 48.0
## 29 5 2 t3 55.0
## 30 6 2 t3 56.0
## 31 7 2 t3 59.0
## 32 8 2 t3 81.0
## 33 9 3 t3 55.0
## 34 10 3 t3 87.0
## 35 11 3 t3 80.0
## 36 12 3 t3 80.0
## 37 1 1 t4 50.0
## 38 2 1 t4 45.0
## 39 3 1 t4 50.0
## 40 4 1 t4 52.0
## 41 5 2 t4 40.0
## 42 6 2 t4 35.0
## 43 7 2 t4 40.0
## 44 8 2 t4 42.0
## 45 9 3 t4 41.0
## 46 10 3 t4 35.0
## 47 11 3 t4 30.0
## 48 12 3 t4 40.0
## 49 1 1 t5 98.0
## 50 2 1 t5 80.0
## 51 3 1 t5 85.0
## 52 4 1 t5 69.0
## 53 5 2 t5 20.0
## 54 6 2 t5 60.0
## 55 7 2 t5 60.0
## 56 8 2 t5 50.0
## 57 9 3 t5 12.0
## 58 10 3 t5 5.0
## 59 11 3 t5 5.0
## 60 12 3 t5 7.5
## 61 1 1 t6 95.0
## 62 2 1 t6 90.0
## 63 3 1 t6 80.0
## 64 4 1 t6 75.0
## 65 5 2 t6 25.0
## 66 6 2 t6 55.0
## 67 7 2 t6 50.0
## 68 8 2 t6 50.0
## 69 9 3 t6 10.0
## 70 10 3 t6 15.0
## 71 11 3 t6 10.0
## 72 12 3 t6 15.0
Con 'key' indicamos la columna con las variables a mover a nuevas columnas y con 'value' los datos de las observaciones de cada una de las nuevas variables:
datos3<-spread(datos2, key=(Time), value=Grado_porcentaje)
datos3#nuestra matriz original
## Individuo Tratamiento t1 t2 t3 t4 t5 t6
## 1 1 1 90 85.0 65.0 50 98.0 95
## 2 2 1 80 87.5 36.0 45 80.0 90
## 3 3 1 90 85.0 47.5 50 85.0 80
## 4 4 1 70 67.0 48.0 52 69.0 75
## 5 5 2 80 90.0 55.0 40 20.0 25
## 6 6 2 65 70.0 56.0 35 60.0 55
## 7 7 2 92 87.5 59.0 40 60.0 50
## 8 8 2 100 99.0 81.0 42 50.0 50
## 9 9 3 85 40.0 55.0 41 12.0 10
## 10 10 3 75 80.0 87.0 35 5.0 15
## 11 11 3 98 85.0 80.0 30 5.0 10
## 12 12 3 98 85.0 80.0 40 7.5 15
Lo que hemos obtenido como resultado es la matriz original de la que partimos antes de crear todas las figuras anteriores.
Ahora vamos a separar por medio de 'spread' una columna en varias. En este caso con el tiempo 1 en función del tratamiento. Hay NAs ya que los individuos de cada tratamiento solo han participado en un tratamiento:
datos4<-spread(datos3, key=Tratamiento, value=t1)
datos4
## Individuo t2 t3 t4 t5 t6 1 2 3
## 1 1 85.0 65.0 50 98.0 95 90 NA NA
## 2 2 87.5 36.0 45 80.0 90 80 NA NA
## 3 3 85.0 47.5 50 85.0 80 90 NA NA
## 4 4 67.0 48.0 52 69.0 75 70 NA NA
## 5 5 90.0 55.0 40 20.0 25 NA 80 NA
## 6 6 70.0 56.0 35 60.0 55 NA 65 NA
## 7 7 87.5 59.0 40 60.0 50 NA 92 NA
## 8 8 99.0 81.0 42 50.0 50 NA 100 NA
## 9 9 40.0 55.0 41 12.0 10 NA NA 85
## 10 10 80.0 87.0 35 5.0 15 NA NA 75
## 11 11 85.0 80.0 30 5.0 10 NA NA 98
## 12 12 85.0 80.0 40 7.5 15 NA NA 98
Con todo lo anterior podemos cambiar la posición de varias columnas en una única columna y al revés. Además podemos añadir nuevas columnas y quitarlas dentro de nuestra matriz de datos. De paso hemos aprendido a representar series temporales de varias maneras.
Departamento de Ciencias de la Vida
Universidad de Alcalá (España)