El término “dataframe” es difícil de traducir al castellano. Podría traducirse como Hoja de datos o Marco de datos. Los dataframes son una clase de objetos especial en R. Normalmente, cuando se realiza un estudio estadístico sobre los sujetos u objetos de una muestra, la información se organiza precisamente en un dataframe: una hoja de datos, en los que cada fila corresponde a un sujeto y cada columna a una variable. La estructura de un data.frame es muy similar a la de una matriz. La diferencia es que una matriz sólo admite valores numéricos, mientras que en un dataframe podemos incluir también datos alfanuméricos.
El siguiente ejemplo nos muestra como crear un data.frame a partir de los datos recogidos sobre una muestra de 10 personas, para cada una de las cuales se ha registrado su edad, sexo y tiempo en minutos que estuvo hablando por teléfono el día antes de la encuesta:
edad <- c(22, 34, 29, 25, 30, 33, 31, 27, 25, 25)
tiempo <- c(14.21, 10.36, 11.89, 13.81, 12.03, 10.99, 12.48, 13.37, 12.29, 11.92)
sexo <- c("M","H","H","M","M","H","M","M","H","H")
misDatos <- data.frame(edad,tiempo,sexo)
misDatos
## edad tiempo sexo
## 1 22 14.21 M
## 2 34 10.36 H
## 3 29 11.89 H
## 4 25 13.81 M
## 5 30 12.03 M
## 6 33 10.99 H
## 7 31 12.48 M
## 8 27 13.37 M
## 9 25 12.29 H
## 10 25 11.92 H
str(misDatos) # Estructura de 'misDatos'
## 'data.frame': 10 obs. of 3 variables:
## $ edad : num 22 34 29 25 30 33 31 27 25 25
## $ tiempo: num 14.2 10.4 11.9 13.8 12 ...
## $ sexo : Factor w/ 2 levels "H","M": 2 1 1 2 2 1 2 2 1 1
names(misDatos) # Nombre de las variables contenidas en 'misDatos'
## [1] "edad" "tiempo" "sexo"
En este ejemplo hemos creado un data.frame llamado misDatos
que contiene a las tres variables edad
, tiempo
y sexo
. La función str()
nos muestra la estructura de este objeto, confirmándonos que es un data.frame de tres variables con 10 observaciones cada una. Nos informa además de que las dos primeras variables son numéricas y la tercera, el sexo, es un factor con dos valores, “H” y “M”. La función names()
por su parte, nos devuelve los nombres de las variables contenidas en misDatos
.
Cuando desde R se leen datos situados en un fichero externo (un fichero de texto, una hoja excel, un archivo de datos de SPSS,…), estos datos se importan en un dataframe.
El acceso a los datos que se encuentran en un data.frame es muy similar al acceso a los datos de una matriz que ya vimos en la sección anterior. Sin embargo, para los data.frames R dispone de algunas funciones que facilitan la tarea de seleccionar o filtrar datos. Así por ejemplo, si queremos ver sólo los datos de los sujetos (filas) 3 a 6, escribiríamos:
misDatos[3:6,]
## edad tiempo sexo
## 3 29 11.89 H
## 4 25 13.81 M
## 5 30 12.03 M
## 6 33 10.99 H
Si queremos seleccionar los datos de edad (primera columna), podemos tratar a misDatos
igual que si fuese una matriz:
misDatos[,1]
## [1] 22 34 29 25 30 33 31 27 25 25
Aunque también podemos referirnos a la columna por su nombre:
misDatos$edad
## [1] 22 34 29 25 30 33 31 27 25 25
Nótese que en este caso hemos de utilizar el nombre del data.frame (misDatos
) seguido del símbolo $
y del nombre de la variable que nos interesa (edad
). De manera equivalente, la selección de esa variable puede realizarse mediante:
misDatos[,"edad"]
## [1] 22 34 29 25 30 33 31 27 25 25
o poniendo el nombre de la variable entre dobles corchetes y entre comillas:
misDatos[["edad"]]
## [1] 22 34 29 25 30 33 31 27 25 25
Así pues, los siguientes comandos son equivalentes y dan el mismo resultado:
mean(misDatos[,1])
mean(misDatos$edad)
mean(misDatos[,"edad"])
mean(misDatos[["edad"]])
## [1] 28.1
El acceso a las variables dentro de un dataframe puede hacerse engorroso cuando hemos de escribir constantemente el nombre del dataframe (en particular si éste es muy largo). Imaginemos, por ejemplo, que para el conjunto misDatos
deseamos construir tablas de frecuencias de cada una de las variables que contiene, una tabla de frecuencias cruzadas para el nivel de estudios por sexo, y que además queremos calcular la edad medio de los individuos de cada sexo. La sintaxis a utilizar sería la siguiente:
table(misDatos$estudios)
table(misDatos$sexo)
table(misDatos$edad)
table(misDatos$sexo,misDatos$edad)
mean(misDatos$edad[misDatos$sexo=="M"])
mean(misDatos$edad[misDatos$sexo=="H"])
Obviamente, escribir tantas veces misDatos resulta tedioso, al margen de que se multiplica el riesgo de cometer errores en la redacción de los comandos. Para evitar este problema podemos utilizar el comando attach()
, cuyo objetivo consiste básicamente en “enganchar” el contenido del dataframe al entorno donde R busca los nombres de variable; de esta forma se puede acceder directamente a las variables del dataframe por su nombre, sin necesidad de que éste tenga que ser precedido con el nombre del dataframe y el símbolo $
; una vez que hayamos acabado nuestra tarea “desenganchamos” el dataframe con detach()
. La tarea anterior, utilizando estos comandos, se puede llevar a cabo mediante:
attach(misDatos)
table(estudios)
table(sexo)
table(edad)
table(sexo,edad)
mean(edad[sexo=="M"])
mean(edad[sexo=="H"])
detach(misDatos)
lo cual es notablemente más simple. No obstante hay que ser extremadamente precavido al utilizar estos comandos ya que cuando se utilizan varios dataframes simultáneamente es muy fácil hacer attachs y detachs en lugares incorrectos, lo que puede conducir a mezclar datos de distinta procedencia y cometer errores inadvertidos. Obsérvese el siguiente ejemplo:
# Creamos el dataframe 'divisas' con la tasa de cambio de algunas monedas
divisas = data.frame(moneda=c("Libra", "Euro", "Rublo"), cambio=c(1.2, 1, 0.02))
divisas
## moneda cambio
## 1 Libra 1.20
## 2 Euro 1.00
## 3 Rublo 0.02
# Creamos un dataframe con el nombre de algunos paises y su moneda nacional
paises = data.frame(pais=c("EEUU", "Venezuela", "Japón"), moneda=c("Dólar", "Bolívar", "Yen"))
paises
## pais moneda
## 1 EEUU Dólar
## 2 Venezuela Bolívar
## 3 Japón Yen
attach(divisas) # Enganchamos 'divisas' al entorno de búsqueda de nombres de variables.
moneda # Se muestra la variable 'moneda' del dataframe 'divisas'
## [1] Libra Euro Rublo
## Levels: Euro Libra Rublo
attach(paises) # ¡CUIDADO! no se ha hecho el 'detach' del datafame 'divisas'
## The following object is masked from divisas:
##
## moneda
moneda # 'moneda' se lee del último dataframe "enganchado", que es 'paises'
## [1] Dólar Bolívar Yen
## Levels: Bolívar Dólar Yen
cambio # ¡Pero esta variable se sigue leyendo del dataframe 'divisas'!
## [1] 1.20 1.00 0.02
# Si, por ejemplo, pegamos los valores de ambas variables pensando que corresponden al mismo dataframe estaríamos metiendo la pata.
paste(moneda,cambio, sep=": ")
## [1] "Dólar: 1.2" "Bolívar: 1" "Yen: 0.02"
detach(paises) # Desenganchamos el dataframe 'paises'
moneda # Recuperamos la variable 'moneda' que estaba en 'divisas'
## [1] Libra Euro Rublo
## Levels: Euro Libra Rublo
detach(divisas) # Desenganchamos 'divisas'
moneda # Ya no hay ninguna variable 'moneda' a la que R pueda acceder directamente por su nombre
## Error in eval(expr, envir, enclos): objeto 'moneda' no encontrado
Por otra parte, si ya existe una variable en el entorno de trabajo con el mismo nombre que alguna variable del dataframe que se engancha mediante el attach()
, la variable del dataframe no resulta accesible ya que queda enmascarada por la variable existente previamente.
El siguiente ejemplo ilustra esta situación: creamos una variable llamada longitud, con 6 valores, y a continuación un dataframe llamado medidas que contiene tres variables con tres valores cada una; en el dataframe una de las variables también se llama longitud:
longitud=c(12,10,11,13,14,17)
medidas=data.frame(longitud=c(6,4,7), peso=c(240,326,315), diametro=c(8,9,9))
Calculamos el valor medio de estas cuatro variables:
mean(longitud)
## [1] 12.8333
mean(medidas$longitud)
## [1] 5.66667
mean(medidas$peso)
## [1] 293.667
mean(medidas$diametro)
## [1] 8.66667
Efectuamos el attach
del dataframe medidas para acceder a sus variables y calculamos de nuevo la media de cada una:
attach(medidas)
## The following objects are masked _by_ .GlobalEnv:
##
## longitud, peso
mean(peso)
## [1] NA
mean(diametro)
## [1] 8.66667
mean(longitud)
## [1] 12.8333
Obsérvese de que R nos advierte de que el objeto longitud ha quedado enmascarado. Vemos que, si bien R ha calculado los valores medios del diámetro y peso correspondientes a las variables del dataframe medidas, la longitud sigue siendo la de la variable longitud previa a hacer el attach
.
El comando with
permite ejecutar una o varias instrucciones sobre las variables de un dataframe accediendo a ellas solamente por su nombre, sin necesidad de utilizar attach
. Resulta particularmente útil para realizar cálculos con las variables dentro de un dataframe.
Si, por ejemplo, queremos calcular la densidad de los objetos cuyas medidas figuran en el dataframe anterior, podemos utilizar la siguiente sintaxis
with(medidas,{
volumen=longitud*pi*(diametro/2)^2 # Calcula el volumen de los objetos
densidad=peso/volumen # Calcula su densidad
densidad # Muestra los valores de densidad
})
## [1] 0.795775 1.281099 0.707355
Obsérvese que el with
no modifica el contenido del dataframe medidas:
medidas
## longitud peso diametro
## 1 6 240 8
## 2 4 326 9
## 3 7 315 9
Si quisiéramos incluir la densidad dentro del dataframe medidas deberíamos proceder del siguiente modo:
medidas$densidad=with(medidas,{
volumen=longitud*pi*(diametro/2)^2 # Calcula el volumen de los objetos
densidad=peso/volumen # Calcula su densidad
densidad # Muestra los valores de densidad
})
medidas # Mostramos el dataframe 'medidas'. Ahora sí que contiene la densidad
## longitud peso diametro densidad
## 1 6 240 8 0.795775
## 2 4 326 9 1.281099
## 3 7 315 9 0.707355
La función subset()
nos permite seleccionar una parte del data.frame. Por ejemplo, si deseamos crear dos dataframes nuevos, uno solo con los hombres y otro con las mujeres utilizaríamos:
hombres=subset(misDatos,sexo=="H")
hombres
## edad tiempo sexo
## 2 34 10.36 H
## 3 29 11.89 H
## 6 33 10.99 H
## 9 25 12.29 H
## 10 25 11.92 H
mujeres=subset(misDatos,sexo=="M")
mujeres
## edad tiempo sexo
## 1 22 14.21 M
## 4 25 13.81 M
## 5 30 12.03 M
## 7 31 12.48 M
## 8 27 13.37 M
Podemos elaborar selecciones más complejas; por ejemplo:
• Sujetos que sean hombres y tengan más de 30 años (la condición “ y ” se especifica mediante el símbolo “ & ”):
mayores=subset(misDatos,sexo=="H" & edad>30)
mayores
## edad tiempo sexo
## 2 34 10.36 H
## 6 33 10.99 H
• Hombres que tengan menos de 30 años y hayan hablado por el móvil más de 12 minutos diarios:
jov_habladores=subset(misDatos,sexo=="H" & edad<30 & tiempo>12)
jov_habladores
## edad tiempo sexo
## 9 25 12.29 H
• Sujetos que tengan menos de 25 o más 30 años (la condición “ o ” se expresa mediante la línea vertical “ | ”):
extremos=subset(misDatos,edad<25|edad>30)
extremos
## edad tiempo sexo
## 1 22 14.21 M
## 2 34 10.36 H
## 6 33 10.99 H
## 7 31 12.48 M
Podemos seleccionar además un subconjunto de variables del data.frame. Por ejemplo, si nos interesan solo la edad y el tiempo de uso del móvil de los hombres de la muestra:
hombres=subset(misDatos,sexo=="H", select=c(edad, tiempo))
hombres
## edad tiempo
## 2 34 10.36
## 3 29 11.89
## 6 33 10.99
## 9 25 12.29
## 10 25 11.92
Construir el subconjunto de las mujeres con edad mayor a 25 y menor a 50 años. Para este subconjunto calcular el tiempo medio de uso del móvil.
Si tenemos dos dataframes con la misma estructura (idénticas variables), pero distintos datos, podemos combinarlos pegando uno a continuación del otro mediante rbind
(acrónimo de rowbind, pegar por filas):
animales1 = data.frame(animal=c("vaca","perro","rana","lagarto","mosca","jilguero"),
clase=c("mamífero","mamífero","anfibio","reptil","insecto","ave"))
animales1
## animal clase
## 1 vaca mamífero
## 2 perro mamífero
## 3 rana anfibio
## 4 lagarto reptil
## 5 mosca insecto
## 6 jilguero ave
animales2 = data.frame(animal=c("atún", "cocodrilo", "gato","rana"), clase=c("pez", "reptil", "mamífero","anfibio"))
animales2
## animal clase
## 1 atún pez
## 2 cocodrilo reptil
## 3 gato mamífero
## 4 rana anfibio
animales3 = rbind(animales1,animales2)
animales3
## animal clase
## 1 vaca mamífero
## 2 perro mamífero
## 3 rana anfibio
## 4 lagarto reptil
## 5 mosca insecto
## 6 jilguero ave
## 7 atún pez
## 8 cocodrilo reptil
## 9 gato mamífero
## 10 rana anfibio
El comando rbind
no controla la posible aparición de casos repetidos en los dos dataframes (podemos comprobar que la rana está repetida en el dataframe ‘animales3’). La función merge()
evita este problema; utilizando la opción all=TRUE
ó all=FALSE
(valor por defecto) se consigue que se muestren todos los datos de ambos dataframes, o solo aquellos que son comunes a ambos
animales4=merge(animales1,animales2)
animales4
## animal clase
## 1 rana anfibio
animales5=merge(animales1,animales2,all=TRUE)
animales5
## animal clase
## 1 jilguero ave
## 2 lagarto reptil
## 3 mosca insecto
## 4 perro mamífero
## 5 rana anfibio
## 6 vaca mamífero
## 7 atún pez
## 8 cocodrilo reptil
## 9 gato mamífero
Si los dataframes tienen estructura distinta, pero contienen variables en común que permiten identificar unívocamente a los mismos objetos en ambos conjuntos, también podemos combinarlos mediante merge()
:
superficieAnimales=data.frame(animal=c("perro","tortuga","jilguero",
"cocodrilo","vaca","lagarto","sardina"),
superficie=c("pelo","placas óseas","plumas",
"escamas","pelo","escamas","escamas"))
superficieAnimales
## animal superficie
## 1 perro pelo
## 2 tortuga placas óseas
## 3 jilguero plumas
## 4 cocodrilo escamas
## 5 vaca pelo
## 6 lagarto escamas
## 7 sardina escamas
merge(animales3,superficieAnimales) # Muestra sólo los animales comunes a ambos dataframes
## animal clase superficie
## 1 cocodrilo reptil escamas
## 2 jilguero ave plumas
## 3 lagarto reptil escamas
## 4 perro mamífero pelo
## 5 vaca mamífero pelo
merge(animales3,superficieAnimales, all.x=TRUE) # Muestra todos los animales del primer dataframe.
## animal clase superficie
## 1 jilguero ave plumas
## 2 lagarto reptil escamas
## 3 mosca insecto <NA>
## 4 perro mamífero pelo
## 5 rana anfibio <NA>
## 6 rana anfibio <NA>
## 7 vaca mamífero pelo
## 8 atún pez <NA>
## 9 cocodrilo reptil escamas
## 10 gato mamífero <NA>
merge(animales3,superficieAnimales, all.y=TRUE) # Muestra todos los animales del segundo dataframe.
## animal clase superficie
## 1 jilguero ave plumas
## 2 lagarto reptil escamas
## 3 perro mamífero pelo
## 4 vaca mamífero pelo
## 5 cocodrilo reptil escamas
## 6 sardina <NA> escamas
## 7 tortuga <NA> placas óseas
merge(animales3,superficieAnimales, all=TRUE) # Muestra todos los animales de ambos dataframes.
## animal clase superficie
## 1 jilguero ave plumas
## 2 lagarto reptil escamas
## 3 mosca insecto <NA>
## 4 perro mamífero pelo
## 5 rana anfibio <NA>
## 6 rana anfibio <NA>
## 7 vaca mamífero pelo
## 8 atún pez <NA>
## 9 cocodrilo reptil escamas
## 10 gato mamífero <NA>
## 11 sardina <NA> escamas
## 12 tortuga <NA> placas óseas
Como vemos, cuando en la combinación de dataframes faltan datos, se rellenan los huecos con valores perdidos (NA)
Para ordenar un dataframe hemos de aplicar la función order()
al elemento o elementos por el que queramos ordenar, y utilizar el resultado de esta función como índice del dataframe.
Por ejemplo, si queremos ordenar el dataframe animales1 por orden alfabético de animales, haríamos:
ordenacion=order(animales1$animal)
ordenacion # Posiciones dentro del dataframe 'animales1' de los animales ordenados alfabéticamente
## [1] 6 4 5 2 3 1
animales1=animales1[ordenacion,] # Se reordenan las filas del dataframe animales1
animales1
## animal clase
## 6 jilguero ave
## 4 lagarto reptil
## 5 mosca insecto
## 2 perro mamífero
## 3 rana anfibio
## 1 vaca mamífero
de modo equivalente, en una línea de código:
animales1=animales1[order(animales1$animal),]
Si queremos ordenar nuestro primer dataframe (misDatos) primero por edad y luego por tiempo utilizando el móvil:
misDatos=misDatos[order(misDatos$edad,misDatos$tiempo),]
misDatos
## edad tiempo sexo
## 1 22 14.21 M
## 10 25 11.92 H
## 9 25 12.29 H
## 4 25 13.81 M
## 8 27 13.37 M
## 3 29 11.89 H
## 5 30 12.03 M
## 7 31 12.48 M
## 6 33 10.99 H
## 2 34 10.36 H
En ocasiones es necesario cambiar la “forma” en que los datos se encuentran dispuestos dentro de un dataframe. A modo de ejemplo, el siguiente archivo contiene los datos de temperatura en el aeropuerto de Gran Canaria medidos una vez cada hora desde el 1 de enero de 2014 (nótese que el archivo se descarga de una dirección http)
tempe=read.csv2("http://www.dma.ulpgc.es/profesores/personal/stat/cursoR4ULPGC/datos/temperatura2014.csv")
head(tempe)
## mes dia temp0 temp1 temp2 temp3 temp4 temp5 temp6 temp7 temp8 temp9 temp10
## 1 1 1 16 16 16 16 15 15 15 15 15 17 19
## 2 1 2 15 15 15 14 14 14 14 14 15 18 18
## 3 1 3 16 16 16 15 15 15 15 16 16 18 19
## 4 1 4 17 17 17 17 17 18 18 18 18 20 21
## 5 1 5 19 19 19 18 18 18 17 17 17 18 20
## 6 1 6 18 17 17 16 15 15 17 17 17 18 19
## temp11 temp12 temp13 temp14 temp15 temp16 temp17 temp18 temp19 temp20 temp21
## 1 19 20 19 19 19 19 18 18 17 16 16
## 2 19 19 20 19 19 19 19 18 17 16 16
## 3 20 20 21 21 20 20 20 18 18 18 17
## 4 21 22 21 21 21 21 20 20 20 20 20
## 5 20 20 20 20 20 20 19 18 18 17 18
## 6 19 19 19 19 19 19 19 18 18 17 17
## temp22 temp23
## 1 15 16
## 2 16 16
## 3 18 18
## 4 20 19
## 5 18 18
## 6 17 17
Como podemos ver, cada fila de este dataframe corresponde a un día del año; las dos primeras columnas especifican dia
y mes
concretos; las restantes columnas, llamadas temp0
hasta temp23
registran la temperatura medida en el aeropuerto cada hora en punto, desde las 0 a las 23 horas. En este dataframe, la variable temperatura (temp
) se encuentra en formato wide
(ancho).
Para convertir este dataframe en otro que tenga una única variable temperatura
medida 24 veces cada día, esto es, en formato long
(largo), utilizaríamos la función reshape()
del siguiente modo:
temperatura=reshape(tempe, idvar = c("mes","dia"), varying = list(3:26),
v.names="temp",direction = "long", timevar="hora")
head(temperatura,10)
## mes dia hora temp
## 1.1.1 1 1 1 16
## 1.2.1 1 2 1 15
## 1.3.1 1 3 1 16
## 1.4.1 1 4 1 17
## 1.5.1 1 5 1 19
## 1.6.1 1 6 1 18
## 1.7.1 1 7 1 16
## 1.8.1 1 8 1 16
## 1.9.1 1 9 1 19
## 1.10.1 1 10 1 14
Aquí:
idvar
es la variable o variables (en este caso mes
y dia
) que se importan del archivo original y que no corresponden a una variable que se encuentra desglosada en varias columnas.
varying
es una lista donde se especifican las posiciones de las columnas que corresponden a la variable que se quiere convertir de formato wide
a formato long
.
v.names
permite especificar el nombre que recibirá la variable que se encuentra en formato wide
una vez que se haya reescrito en formato long
(o al revés)
direction
especifica la dirección en que se va a reformatear el dataframe (long
, como en este caso, o wide
)
timevar
nombre de la variable que codifica el índice (número de orden) de cada observación. Normalmente corresponde a la secuencia temporal en que se han realizado las observaciones.
Como vemos, como resultado del reshape
ahora tenemos una única variable temperatura
y se ha creado la variable hora
; por defecto, el dataframe está ordenado por esta última variable. Si queremos ordenarlo primero por mes, luego por día y por último por hora, utilizamos la función order()
:
ord=with(temperatura, order(mes,dia,hora))
temperatura=temperatura[ord,]
head(temperatura,10)
## mes dia hora temp
## 1.1.1 1 1 1 16
## 1.1.2 1 1 2 16
## 1.1.3 1 1 3 16
## 1.1.4 1 1 4 16
## 1.1.5 1 1 5 15
## 1.1.6 1 1 6 15
## 1.1.7 1 1 7 15
## 1.1.8 1 1 8 15
## 1.1.9 1 1 9 15
## 1.1.10 1 1 10 17
Además, la variable hora
no corresponde, en realidad a la hora, sino al orden de cada observación dentro de cada día; si tenemos en cuenta que la primera observación se realiza a las cero horas, la segunda a la una, la tercera a las dos, etc, podemos convertir esta variable en la hora real de la observación simplemente restándole una unidad:
temperatura$hora=temperatura$hora-1
head(temperatura,10)
## mes dia hora temp
## 1.1.1 1 1 0 16
## 1.1.2 1 1 1 16
## 1.1.3 1 1 2 16
## 1.1.4 1 1 3 16
## 1.1.5 1 1 4 15
## 1.1.6 1 1 5 15
## 1.1.7 1 1 6 15
## 1.1.8 1 1 7 15
## 1.1.9 1 1 8 15
## 1.1.10 1 1 9 17
Representamos a continuación gráficamente la secuencia de observaciones de temperatura a lo largo del periodo observado (1 de enero a 11 de julio). Para ello creamos en primer lugar la variable fecha
(ver la sección Fechas de este curso).
fecha=with(temperatura,paste(paste("2014",mes,dia,sep="-"),hora,sep=" "))
temperatura$fecha=as.POSIXlt(fecha,format="%Y-%m-%d %H")
with(temperatura,plot(fecha,temp,type="l",ylab="Temperatura (ºC)",main="Temperaturas aeropuerto GC 2014"))
La lista representa el siguiente nivel de complejidad en las estructuras de datos que R es capaz de manejar. Podemos entender una lista como un contenedor de objetos que pueden ser de cualquier clase: números, vectores, matrices, funciones, data.frames, incluso otras listas. Una lista puede contener a la vez varios de estos objetos, que pueden ser además de distintas dimensiones.
Por ejemplo, podemos crear una lista que contenga el data.frame misDatos
, la matriz A
, la matrizM
, el vector x=c(1,2,3,4)
y la constante e=exp(1)
:
A=matrix(1:9,nrow=3)
M=matrix(1,4,nrow=2)
MiLista <- list(misDatos,A,M=M,x=c(1,2,3,4),e=exp(1))
MiLista
## [[1]]
## edad tiempo sexo
## 1 22 14.21 M
## 10 25 11.92 H
## 9 25 12.29 H
## 4 25 13.81 M
## 8 27 13.37 M
## 3 29 11.89 H
## 5 30 12.03 M
## 7 31 12.48 M
## 6 33 10.99 H
## 2 34 10.36 H
##
## [[2]]
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
## [3,] 3 6 9
##
## $M
## [,1] [,2] [,3] [,4]
## [1,] 1 1 1 1
## [2,] 1 1 1 1
##
## $x
## [1] 1 2 3 4
##
## $e
## [1] 2.71828
Obsérvese a continuación como podemos acceder a los distintos elementos de la lista. Póngase especial atención a lo que ocurre con los elementos misDatos
y A
, cuyo nombre no se utilizó explícitamente en la declaración de la lista:
MiLista$misDatos
## NULL
MiLista[[1]]
## edad tiempo sexo
## 1 22 14.21 M
## 10 25 11.92 H
## 9 25 12.29 H
## 4 25 13.81 M
## 8 27 13.37 M
## 3 29 11.89 H
## 5 30 12.03 M
## 7 31 12.48 M
## 6 33 10.99 H
## 2 34 10.36 H
MiLista$A
## NULL
MiLista[[2]]
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
## [3,] 3 6 9
MiLista$M
## [,1] [,2] [,3] [,4]
## [1,] 1 1 1 1
## [2,] 1 1 1 1
MiLista$x
## [1] 1 2 3 4
MiLista$e
## [1] 2.71828
Como vemos, para acceder a los objetos que forman parte de una lista, basta con añadir su nombre a continuación del de la lista, separados por el símbolo $
, o bien con el índice de posición dentro de la lista con doble corchete [[]]
. Nótese que los objetos misDatos
y A
no tienen nombre dentro de la lista, por lo que hemos de referirnos a ellos como MiLista[[1]]
o MiLista[[2]]
. Sin embargo, el objeto M
sí que tiene nombre. Para que un objeto dentro de una lista tenga nombre, éste debe declararse explícitamente en la construcción de la lista, tal como se hizo con M
, x
o e
.
R utiliza las listas, sobre, todo como salida de los distintos procedimientos estadísticos. Así, por ejemplo, al realizar un contraste de medias de dos poblaciones, R calcula, entre otras cosas, la diferencia de medias muestrales, el valor del estadístico de contraste, el p-valor del test y el intervalo de confianza para la diferencia observada. Todos estos términos forman parte de una lista. La sintaxis para comparar, por ejemplo, el tiempo medio de uso del móvil entre hombres y mujeres a partir de nuestros datos sería:
t.test(tiempo~sexo, data=misDatos)
##
## Welch Two Sample t-test
##
## data: tiempo by sexo
## t = -3.133, df = 7.854, p-value = 0.0143
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -2.937818 -0.442182
## sample estimates:
## mean in group H mean in group M
## 11.49 13.18
Si guardamos el resultado de este contraste en el objeto contraste
, podemos observar que tiene estructura de lista:
contraste=t.test(tiempo~sexo, data=misDatos)
str(contraste)
## List of 9
## $ statistic : Named num -3.13
## ..- attr(*, "names")= chr "t"
## $ parameter : Named num 7.85
## ..- attr(*, "names")= chr "df"
## $ p.value : num 0.0143
## $ conf.int : num [1:2] -2.938 -0.442
## ..- attr(*, "conf.level")= num 0.95
## $ estimate : Named num [1:2] 11.5 13.2
## ..- attr(*, "names")= chr [1:2] "mean in group H" "mean in group M"
## $ null.value : Named num 0
## ..- attr(*, "names")= chr "difference in means"
## $ alternative: chr "two.sided"
## $ method : chr "Welch Two Sample t-test"
## $ data.name : chr "tiempo by sexo"
## - attr(*, "class")= chr "htest"
Si deseamos extraer, por ejemplo, solo el intervalo de confianza de la lista anterior nos bastaría con ejecutar:
contraste$conf.int
## [1] -2.937818 -0.442182
## attr(,"conf.level")
## [1] 0.95
También podemos extraerlo directamente en la llamada al procedimiento t.test()
:
t.test(tiempo~sexo, data=misDatos)$conf.int
## [1] -2.937818 -0.442182
## attr(,"conf.level")
## [1] 0.95
© 2016 Angelo Santana, Carmen N. Hernández, Departamento de Matemáticas ULPGC