En este primer ejercicio vamos a trabajar con los paquetes de R.
Empezamos comprobando qué paquetes tenemos instalados y después
trabajamos con MASS y survival.
Para consultar los paquetes disponibles podemos utilizar
library() sin indicar ningún paquete entre los
paréntesis.
# Consultamos los paquetes disponibles
library()
Al ejecutar library() podemos ver los paquetes que
tenemos disponibles en nuestra instalación de R.
A continuación instalamos los paquetes MASS y
survival. Para ello utilizamos
install.packages(). Este paso solo es necesario si todavía
no los tenemos instalados.
# Instalamos los paquetes indicados en el ejercicio
install.packages("MASS")
install.packages("survival")
He utilizado eval=FALSE para que R Markdown muestre el
código pero no vuelva a instalar los paquetes cada vez que compilemos el
documento.
Una vez instalados, los cargamos mediante library() para
poder utilizarlos durante la sesión de R.
# Cargamos los paquetes
library(MASS)
library(survival)
La diferencia entre ambos pasos es sencilla:
install.packages() instala el paquete en el ordenador,
mientras que library() lo carga en la sesión de R en la que
estamos trabajando.
Después consultamos la información de los dos paquetes mediante
packageDescription().
# Consultamos la información del paquete MASS
packageDescription("MASS")
## Package: MASS
## Priority: recommended
## Version: 7.3-66
## Date: 2026-07-15
## Revision: $Rev: 3693 $
## Depends: R (>= 4.4.0), grDevices, graphics, stats, utils
## Imports: methods
## Suggests: lattice, nlme, nnet, survival
## Authors@R: c(person("Brian", "Ripley", role = c("aut", "cre", "cph"),
## email = "Brian.Ripley@R-project.org"), person("Bill",
## "Venables", role = c("aut", "cph")), person(c("Douglas", "M."),
## "Bates", role = "ctb"), person("Kurt", "Hornik", role = "trl",
## comment = "partial port ca 1998"), person("Albrecht",
## "Gebhardt", role = "trl", comment = "partial port ca 1998"),
## person("David", "Firth", role = "ctb", comment = "support
## functions for polr"))
## Description: Functions and datasets to support Venables and Ripley,
## "Modern Applied Statistics with S" (4th edition, 2002).
## Title: Support Functions and Datasets for Venables and Ripley's MASS
## LazyData: yes
## ByteCompile: yes
## License: GPL-2 | GPL-3
## URL: http://www.stats.ox.ac.uk/pub/MASS4/
## Contact: <MASS@stats.ox.ac.uk>
## NeedsCompilation: yes
## Packaged: 2026-07-15 10:10:22 UTC; ripley
## Author: Brian Ripley [aut, cre, cph], Bill Venables [aut, cph], Douglas
## M. Bates [ctb], Kurt Hornik [trl] (partial port ca 1998),
## Albrecht Gebhardt [trl] (partial port ca 1998), David Firth
## [ctb] (support functions for polr)
## Maintainer: Brian Ripley <Brian.Ripley@R-project.org>
## Repository: CRAN
## Date/Publication: 2026-07-15 10:58:26 UTC
## Built: R 4.6.1; x86_64-w64-mingw32; 2026-10-26 04:10:36 UTC; windows
## Archs: x64
## RemoteType: standard
## RemotePkgRef: MASS
## RemoteRef: MASS
## RemoteRepos: https://cran.rstudio.com
## RemoteSha.Version: 7.3-66
##
## -- File: C:/Users/AlbaM/AppData/Local/Programs/R/R-4.6.1/library/MASS/Meta/package.rds
# Consultamos la información del paquete survival
packageDescription("survival")
## Title: Survival Analysis
## Priority: recommended
## Package: survival
## Version: 3.8-12
## Date: 2026-09-02
## Depends: R (>= 4.1.0)
## Imports: graphics, Matrix, methods, splines, stats, utils
## LazyData: Yes
## LazyDataCompression: xz
## ByteCompile: Yes
## Authors@R: c(person(c("Terry", "M"), "Therneau",
## email="terry.therneau@proton.me", role=c("aut", "cre")),
## person("Thomas", "Lumley", role=c("ctb", "trl"),
## comment="original S->R port and R maintainer until 2009"),
## person("Atkinson", "Elizabeth", role="ctb"), person("Crowson",
## "Cynthia", role="ctb"))
## Description: Contains the core survival analysis routines, including
## definition of Surv objects, Kaplan-Meier and Aalen-Johansen
## (multi-state) curves, Cox models, and parametric accelerated
## failure time models.
## License: LGPL (>= 2)
## URL: https://github.com/therneau/survival
## NeedsCompilation: yes
## Packaged: 2026-09-09 11:38:39 UTC; therneau
## Author: Terry M Therneau [aut, cre], Thomas Lumley [ctb, trl] (original
## S->R port and R maintainer until 2009), Atkinson Elizabeth
## [ctb], Crowson Cynthia [ctb]
## Maintainer: Terry M Therneau <terry.therneau@proton.me>
## Repository: CRAN
## Date/Publication: 2026-09-09 18:10:02 UTC
## Built: R 4.6.1; x86_64-w64-mingw32; 2026-10-26 05:57:12 UTC; windows
## Archs: x64
## RemoteType: standard
## RemotePkgRef: survival
## RemoteRef: survival
## RemoteRepos: https://cran.rstudio.com
## RemoteSha.Version: 3.8-12
##
## -- File: C:/Users/AlbaM/AppData/Local/Programs/R/R-4.6.1/library/survival/Meta/package.rds
Con packageDescription() podemos consultar información
sobre cada paquete, como su descripción y otros datos relacionados con
su contenido.
Por último, buscamos información sobre Rcmdr. Para ello
utilizamos ??, que permite realizar una búsqueda en la
ayuda de R.
# Buscamos información relacionada con Rcmdr
??Rcmdr
## starting httpd help server ... done
Con este ejercicio hemos visto la diferencia entre instalar y cargar
un paquete, además de aprender a consultar su información y buscar ayuda
desde R. Lo más importante es tener claro que normalmente un paquete se
instala una vez, pero debemos cargarlo con library() cuando
queremos utilizarlo en una sesión.
En este ejercicio vamos a practicar la importación de dos tipos de archivos diferentes. Primero trabajamos con un archivo de texto y después con un archivo CSV. Antes de hacer los cálculos, comprobamos siempre que los datos se han importado correctamente y vemos qué variables contiene cada archivo.
Para esta primera parte vamos a utilizar el archivo
data.txt.txt. Lo importamos mediante
read.table() y guardamos los datos en el objeto
datos_txt.
Como la primera fila del archivo contiene los nombres de las
variables, utilizamos header = TRUE.
# Importamos el archivo de texto
datos_txt <- read.table(
"C:/Users/AlbaM/OneDrive - Enza Zaden/Escritorio/software/data.txt.txt",
header = TRUE
)
# Visualizamos los primeros registros
head(datos_txt)
## edad peso altura
## 1 23 58 162
## 2 28 64 168
## 3 31 70 171
## 4 35 67 165
## 5 42 75 174
## 6 26 61 160
# Consultamos los nombres de las variables
names(datos_txt)
## [1] "edad" "peso" "altura"
# Comprobamos la estructura de los datos
str(datos_txt)
## 'data.frame': 15 obs. of 3 variables:
## $ edad : int 23 28 31 35 42 26 39 45 33 29 ...
## $ peso : int 58 64 70 67 75 61 72 78 66 63 ...
## $ altura: int 162 168 171 165 174 160 169 176 167 164 ...
Antes de calcular ningún resumen, utilizamos head(),
names() y str() para comprobar que el archivo
se ha leído correctamente y conocer las variables que contiene.
Si las variables del archivo son edad, peso
y altura, podemos obtener su resumen estadístico mediante
summary().
# Obtenemos el resumen estadístico de la edad
summary(datos_txt$edad)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 23.00 28.50 33.00 33.27 38.00 45.00
# Obtenemos el resumen estadístico del peso
summary(datos_txt$peso)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 58.0 63.5 67.0 67.8 73.0 78.0
# Obtenemos el resumen estadístico de la altura
summary(datos_txt$altura)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 160.0 164.5 168.0 168.0 171.5 176.0
Con summary() obtenemos una primera descripción de cada
variable mediante valores como el mínimo, el primer cuartil, la mediana,
la media, el tercer cuartil y el máximo.
heart.csv y
uso de fivenum()Para la segunda parte he elegido trabajar con el archivo
heart.csv. Primero importamos el archivo y guardamos los
datos en el objeto heart.
# Importamos el archivo heart.csv
heart <- read.csv("heart.csv")
# Visualizamos los primeros registros
head(heart)
## age sex cp trestbps chol fbs restecg thalach exang oldpeak slope ca thal
## 1 70 1 3 130 322 0 2 109 0 2.4 1 3 1
## 2 67 0 2 115 564 0 2 160 0 1.6 1 0 3
## 3 57 1 1 124 261 0 0 141 0 0.3 0 0 3
## 4 64 1 3 128 263 0 0 105 1 0.2 1 1 3
## 5 74 0 1 120 269 0 2 121 1 0.2 0 1 1
## 6 65 1 3 120 177 0 0 140 0 0.4 0 0 3
## target
## 1 1
## 2 0
## 3 1
## 4 0
## 5 0
## 6 0
# Consultamos los nombres de las variables
names(heart)
## [1] "age" "sex" "cp" "trestbps" "chol" "fbs"
## [7] "restecg" "thalach" "exang" "oldpeak" "slope" "ca"
## [13] "thal" "target"
# Comprobamos la estructura de los datos
str(heart)
## 'data.frame': 270 obs. of 14 variables:
## $ age : int 70 67 57 64 74 65 56 59 60 63 ...
## $ sex : int 1 0 1 1 0 1 1 1 1 0 ...
## $ cp : int 3 2 1 3 1 3 2 3 3 3 ...
## $ trestbps: int 130 115 124 128 120 120 130 110 140 150 ...
## $ chol : int 322 564 261 263 269 177 256 239 293 407 ...
## $ fbs : int 0 0 0 0 0 0 1 0 0 0 ...
## $ restecg : int 2 2 0 0 2 0 2 2 2 2 ...
## $ thalach : int 109 160 141 105 121 140 142 142 170 154 ...
## $ exang : int 0 0 0 1 1 0 1 1 0 0 ...
## $ oldpeak : num 2.4 1.6 0.3 0.2 0.2 0.4 0.6 1.2 1.2 4 ...
## $ slope : int 1 1 0 1 0 0 1 1 1 1 ...
## $ ca : int 3 0 0 1 1 0 1 1 2 3 ...
## $ thal : int 1 3 3 3 1 3 2 3 3 3 ...
## $ target : int 1 0 1 0 0 0 1 1 1 1 ...
Al explorar el archivo comprobamos que contiene 270 observaciones y
14 variables: age, sex, cp,
trestbps, chol, fbs,
restecg, thalach, exang,
oldpeak, slope, ca,
thal y target.
Para aplicar fivenum() he elegido las variables
age y chol, ya que ambas son numéricas y
resultan sencillas de interpretar.
# Obtenemos los cinco valores resumen de la variable age
fivenum(heart$age)
## [1] 29 48 55 61 77
# Obtenemos los cinco valores resumen de la variable chol
fivenum(heart$chol)
## [1] 126 213 245 281 564
La función fivenum() nos permite resumir cada variable
mediante cinco valores: el mínimo, dos valores intermedios, la mediana y
el máximo.
De esta forma hemos practicado la importación de dos formatos
diferentes y hemos utilizado summary() y
fivenum() para obtener una primera descripción de algunas
de sus variables.
En este ejercicio vamos a trabajar con el conjunto de datos
anorexia, que se encuentra en el paquete MASS.
Primero cargamos el paquete y activamos los datos. Después mostramos los
primeros registros para ver las variables con las que vamos a
trabajar.
# Cargamos el paquete MASS
library(MASS)
# Activamos el conjunto de datos anorexia
data("anorexia")
# Mostramos los primeros registros
head(anorexia)
## Treat Prewt Postwt
## 1 Cont 80.7 80.2
## 2 Cont 89.4 80.1
## 3 Cont 91.8 86.4
## 4 Cont 74.0 86.3
## 5 Cont 78.1 76.1
## 6 Cont 88.3 78.1
Al visualizar los primeros registros vemos que anorexia
contiene tres variables: Treat, Prewt y
Postwt. Treat identifica el tratamiento,
mientras que Prewt y Postwt recogen los
valores de peso antes y después del tratamiento. 【1-65f6da】
Antes de seguir trabajando con los datos, comprobamos si existen
valores perdidos mediante is.na(). Esta función devuelve
TRUE cuando encuentra un valor perdido y FALSE
cuando el valor está registrado.
Utilizamos table() para contar los resultados:
# Comprobamos si existen valores perdidos
table(is.na(anorexia))
##
## FALSE
## 216
En la solución del LAB obtenemos 216 valores FALSE, por
lo que no aparecen valores perdidos en el conjunto de datos.
【1-65f6da】
NULLTambién comprobamos si el objeto anorexia es
NULL. Para ello utilizamos is.null().
# Comprobamos si el conjunto de datos es NULL
table(is.null(anorexia))
##
## FALSE
## 1
En este caso obtenemos FALSE, lo que nos indica que el
objeto anorexia no es NULL. 【1-65f6da】
Es importante diferenciar ambos conceptos: NA se utiliza
para comprobar valores ausentes dentro de los datos, mientras que
NULL indica la ausencia del propio objeto o contenido.
TreatPor último, vamos a trabajar con la variable Treat. En
lugar de modificar directamente los datos originales, creamos un nuevo
factor llamado anorexia_F.
Utilizamos factor() para mantener los niveles originales
y asignarles etiquetas más descriptivas.
# Creamos un factor a partir de la variable Treat
# y asignamos nuevas etiquetas a sus tres niveles
anorexia_F <- factor(
anorexia$Treat,
levels = c("CBT", "Cont", "FT"),
labels = c("Cogn Beh Tr", "Contr", "Fam Tr"))
# Mostramos el factor creado
anorexia_F
## [1] Contr Contr Contr Contr Contr Contr
## [7] Contr Contr Contr Contr Contr Contr
## [13] Contr Contr Contr Contr Contr Contr
## [19] Contr Contr Contr Contr Contr Contr
## [25] Contr Contr Cogn Beh Tr Cogn Beh Tr Cogn Beh Tr Cogn Beh Tr
## [31] Cogn Beh Tr Cogn Beh Tr Cogn Beh Tr Cogn Beh Tr Cogn Beh Tr Cogn Beh Tr
## [37] Cogn Beh Tr Cogn Beh Tr Cogn Beh Tr Cogn Beh Tr Cogn Beh Tr Cogn Beh Tr
## [43] Cogn Beh Tr Cogn Beh Tr Cogn Beh Tr Cogn Beh Tr Cogn Beh Tr Cogn Beh Tr
## [49] Cogn Beh Tr Cogn Beh Tr Cogn Beh Tr Cogn Beh Tr Cogn Beh Tr Cogn Beh Tr
## [55] Cogn Beh Tr Fam Tr Fam Tr Fam Tr Fam Tr Fam Tr
## [61] Fam Tr Fam Tr Fam Tr Fam Tr Fam Tr Fam Tr
## [67] Fam Tr Fam Tr Fam Tr Fam Tr Fam Tr Fam Tr
## Levels: Cogn Beh Tr Contr Fam Tr
Con levels indicamos los tres valores originales de
Treat y mediante labels asignamos las nuevas
etiquetas. De esta forma mantenemos la información original, pero los
distintos tratamientos quedan identificados de una manera más
descriptiva.
Al mostrar anorexia_F podemos comprobar que R ha
aplicado las nuevas etiquetas y que el factor mantiene tres niveles.
En este ejercicio vamos a practicar la exportación de datos desde R a
diferentes formatos. Para ello utilizamos los conjuntos de datos
biopsy y Melanoma, incluidos en el paquete
MASS.
biopsyPrimero cargamos el paquete MASS, activamos el conjunto
de datos biopsy y mostramos sus primeros registros.
# Cargamos el paquete MASS
library(MASS)
# Activamos el conjunto de datos biopsy
data("biopsy")
# Visualizamos los primeros registros
head(biopsy)
## ID V1 V2 V3 V4 V5 V6 V7 V8 V9 class
## 1 1000025 5 1 1 1 2 1 3 1 1 benign
## 2 1002945 5 4 4 5 7 10 3 2 1 benign
## 3 1015425 3 1 1 1 2 2 3 1 1 benign
## 4 1016277 6 8 8 1 3 4 3 7 1 benign
## 5 1017023 4 1 1 3 2 1 3 1 1 benign
## 6 1017122 8 10 10 8 7 10 9 7 1 malignant
A continuación utilizamos write.csv() para guardar el
conjunto de datos en formato CSV.
# Exportamos biopsy en formato CSV
write.csv(biopsy,file = "biopsy.csv")
Con write.csv() indicamos el conjunto de datos que
queremos exportar y el nombre que tendrá el archivo.
MelanomaAhora trabajamos con el conjunto de datos Melanoma.
Primero lo activamos y observamos sus primeros registros.
# Activamos el conjunto de datos Melanoma
data("Melanoma")
# Visualizamos los primeros registros
head(Melanoma)
## time status sex age year thickness ulcer
## 1 10 3 1 76 1972 6.76 1
## 2 30 3 1 56 1968 0.65 0
## 3 35 2 1 41 1977 1.34 0
## 4 99 3 0 71 1968 2.90 0
## 5 185 1 1 52 1965 12.08 1
## 6 204 1 1 28 1971 4.84 1
Primero exportamos Melanoma a formato CSV.
# Exportamos Melanoma en formato CSV
write.csv(Melanoma,file = "Melanoma.csv")
Después utilizamos write.table() para guardar el mismo
conjunto de datos en formato TXT.
# Exportamos Melanoma en formato TXT
write.table(Melanoma,file = "melanoma.txt")
Por último, el ejercicio también plantea exportar
Melanoma a formato Excel mediante el paquete
xlsx.
En este caso el paquete xlsx necesita Java para poder
ejecutarse. Aunque el paquete está instalado, R no encuentra
correctamente la configuración de Java en mi equipo. Por este motivo,
mantengo el código correspondiente a la exportación para mostrar el
procedimiento, pero utilizo eval=FALSE para evitar que este
bloque se ejecute al compilar el documento.
# Cargamos el paquete xlsx
library(xlsx)
# Exportamos Melanoma en formato Excel
write.xlsx( Melanoma,file = "melanoma.xlsx")
La opción eval=FALSE indica a R Markdown que
muestre el código en el documento, pero que no lo ejecute
durante el Knit. De esta forma podemos incluir el procedimiento
utilizado para exportar a Excel sin que el problema de configuración de
Java interrumpa la compilación del documento.
Finalmente, comprobamos que los archivos que sí hemos ejecutado se han creado correctamente.
# Comprobamos el directorio donde se han guardado los archivos
getwd()
## [1] "C:/Users/AlbaM/OneDrive - Enza Zaden/Escritorio/software"
# Comprobamos que los archivos ejecutados se han creado
file.exists("biopsy.csv")
## [1] TRUE
file.exists("melanoma.csv")
## [1] TRUE
file.exists("melanoma.txt")
## [1] TRUE
Si obtenemos TRUE, significa que el archivo
correspondiente se ha creado correctamente.
En este ejercicio hemos utilizado write.csv() para
exportar archivos CSV y write.table() para generar un
archivo de texto. También hemos visto el procedimiento con
write.xlsx() para exportar a Excel, aunque en este caso no
se ejecuta debido a la dependencia de Java del paquete
xlsx.
birthwtEn este ejercicio vamos a trabajar con el conjunto de datos
birthwt, incluido en el paquete MASS. Primero
cargamos los datos y observamos los primeros registros para conocer las
variables con las que vamos a trabajar.
# Cargamos el paquete MASS
library(MASS)
# Activamos el conjunto de datos birthwt
data("birthwt")
# Observamos los primeros registros
head(birthwt)
## low age lwt race smoke ptl ht ui ftv bwt
## 85 0 19 182 2 0 0 0 1 0 2523
## 86 0 33 155 3 0 0 0 0 3 2551
## 87 0 20 105 1 1 0 0 0 1 2557
## 88 0 21 108 1 1 0 0 1 2 2594
## 89 0 18 107 1 1 0 0 1 0 2600
## 91 0 21 124 3 0 0 0 0 0 2622
Una vez cargados los datos, vamos resolviendo las preguntas del ejercicio utilizando las variables que necesitamos en cada caso.
Primero buscamos la edad máxima registrada en la variable
age. Para ello utilizamos max().
# Buscamos la edad máxima
max(birthwt$age)
## [1] 45
El resultado es 45 años, por lo que esta es la edad máxima registrada en el conjunto de datos.
Para encontrar la edad mínima hacemos lo mismo, pero utilizando
min().
# Buscamos la edad mínima
min(birthwt$age)
## [1] 14
En este caso obtenemos 14 años, que corresponde a la edad mínima registrada.
Para conocer el rango de las edades calculamos la diferencia entre el valor máximo y el mínimo.
# Calculamos el rango de las edades
rango <- max(birthwt$age) - min(birthwt$age)
rango
## [1] 31
El rango es de 31 años, resultado de restar la edad mínima, 14 años, a la máxima, 45 años.
smoke correspondiente al
menor peso al nacerAhora queremos localizar la observación que tiene el menor valor de
bwt y comprobar qué valor presenta la variable
smoke.
Para ello combinamos min() con una condición dentro de
los corchetes.
# Buscamos el valor de smoke correspondiente al menor peso al nacer
birthwt$smoke[birthwt$bwt == min(birthwt$bwt)]
## [1] 1
Primero, min(birthwt$bwt) busca el menor peso al nacer.
Después utilizamos ese resultado como condición para seleccionar el
valor correspondiente de smoke.
El resultado obtenido es 1.
En este apartado buscamos el valor de bwt
correspondiente a la observación con la mayor edad.
# Buscamos el peso al nacer correspondiente a la edad máxima
birthwt$bwt[birthwt$age == max(birthwt$age)]
## [1] 4990
Primero localizamos la edad máxima mediante
max(birthwt$age) y utilizamos esa condición para
seleccionar el peso al nacer.
El resultado obtenido es 4990.
ftv es menor
que 2Por último, seleccionamos los valores de bwt
correspondientes a las observaciones en las que ftv es
menor que 2.
# Seleccionamos los pesos al nacer cuando ftv es menor que 2
birthwt$bwt[birthwt$ftv < 2]
## [1] 2523 2557 2600 2622 2637 2637 2663 2665 2722 2733 2751 2769 2769 2778 2807
## [16] 2821 2836 2863 2877 2906 2920 2920 2920 2948 2948 2977 2977 2922 3033 3062
## [31] 3062 3062 3062 3090 3090 3100 3104 3132 3175 3175 3203 3203 3203 3225 3225
## [46] 3232 3234 3260 3274 3317 3317 3331 3374 3374 3402 3416 3444 3459 3460 3473
## [61] 3544 3487 3544 3572 3572 3586 3600 3614 3614 3629 3637 3643 3651 3651 3651
## [76] 3651 3699 3728 3756 3770 3770 3770 3790 3799 3827 3884 3912 3940 3941 3941
## [91] 3969 3997 3997 4054 4054 4111 4174 4238 4593 4990 709 1135 1330 1474 1588
## [106] 1588 1701 1729 1790 1818 1885 1893 1899 1928 1936 1970 2055 2055 2084 2084
## [121] 2100 2125 2187 2187 2211 2225 2240 2240 2282 2296 2296 2325 2353 2353 2367
## [136] 2381 2381 2381 2410 2410 2410 2424 2442 2466 2466 2495 2495
En este caso obtenemos varios resultados porque hay diferentes
observaciones que cumplen la condición ftv < 2.
Con este último apartado hemos utilizado una condición para filtrar
los datos y seleccionar únicamente los valores de bwt que
cumplen el criterio indicado.
anorexiaEn este ejercicio volvemos a trabajar con el conjunto de datos
anorexia. Queremos crear una matriz que contenga únicamente
los valores de peso antes (Prewt) y después
(Postwt) del tratamiento.
Como ya hemos trabajado anteriormente con anorexia,
conocemos las variables que contiene. Aun así, cargamos el paquete
MASS y activamos el conjunto de datos para asegurarnos de
que está disponible al ejecutar el documento.
# Cargamos el paquete y activamos el conjunto de datos anorexia
library(MASS)
data("anorexia")
Para crear la matriz, primero unimos los valores de
Prewt y Postwt mediante c().
Después utilizamos matrix() e indicamos
ncol = 2, ya que queremos que la matriz tenga dos
columnas.
# Creamos una matriz con los pesos antes y después del tratamiento
matr_anorexia <- matrix(c(anorexia$Prewt, anorexia$Postwt),ncol = 2)
# Mostramos las primeras filas para comprobar el resultado
head(matr_anorexia)
## [,1] [,2]
## [1,] 80.7 80.2
## [2,] 89.4 80.1
## [3,] 91.8 86.4
## [4,] 74.0 86.3
## [5,] 78.1 76.1
## [6,] 88.3 78.1
Al utilizar ncol = 2, indicamos que la matriz debe tener
dos columnas. La primera contiene los valores de Prewt y la
segunda los valores de Postwt.
Con head() comprobamos las primeras filas y podemos ver
que cada fila mantiene los valores de peso antes y después del
tratamiento para la misma observación.
data.frameEn este ejercicio vamos a crear el conjunto de datos
Trat_Pulmon a partir de los valores proporcionados en el
enunciado. El conjunto contiene 25 registros y seis variables:
identificador, edad, sexo, peso, altura y consumo de tabaco.
Primero creamos cada una de las variables y después las reunimos en
un único data.frame.
# Introducimos los datos proporcionados en el enunciado
Identificador <- c("I1","I2","I3","I4","I5","I6","I7","I8","I9","I10","I11","I12","I13","I14","I15","I16","I17","I18","I19","I20","I21","I22","I23","I24","I25")
Edad <- c(23,24,21,22,23,25,26,24,21,22,23,25,26,24,22,21,25,26,24,21,25,27,26,22,29)
# Según el enunciado, 1 corresponde a mujeres y 2 a hombres
Sexo <- c(1,2,1,1,1,2,2,2,1,2,1,2,2,2,1,1,1,2,2,2,1,2,1,1,2)
Peso <- c(76.5,81.2,79.3,59.5,67.3,78.6,67.9,100.2,97.8,56.4,65.4,67.5,87.4,99.7,87.6,93.4,65.4,73.7,85.1,61.2,54.8,103.4,65.8,71.7,85.0)
# Altura expresada en centímetros
Alt <- c(165,154,178,165,164,175,182,165,178,165,158,183,184,164,189,167,182,179,165,158,183,184,189,166,175)
Fuma <- c("SÍ","NO","SÍ","SÍ","NO","NO","NO","SÍ","SÍ","SÍ","NO","NO","SÍ","SÍ","SÍ","SÍ","NO","NO","SÍ","SÍ","SÍ","NO","SÍ","NO","SÍ")
# Reunimos todas las variables en un único data frame
Trat_Pulmon <- data.frame(Identificador, Edad, Sexo, Peso, Alt, Fuma)
# Mostramos el conjunto creado
Trat_Pulmon
## Identificador Edad Sexo Peso Alt Fuma
## 1 I1 23 1 76.5 165 SÍ
## 2 I2 24 2 81.2 154 NO
## 3 I3 21 1 79.3 178 SÍ
## 4 I4 22 1 59.5 165 SÍ
## 5 I5 23 1 67.3 164 NO
## 6 I6 25 2 78.6 175 NO
## 7 I7 26 2 67.9 182 NO
## 8 I8 24 2 100.2 165 SÍ
## 9 I9 21 1 97.8 178 SÍ
## 10 I10 22 2 56.4 165 SÍ
## 11 I11 23 1 65.4 158 NO
## 12 I12 25 2 67.5 183 NO
## 13 I13 26 2 87.4 184 SÍ
## 14 I14 24 2 99.7 164 SÍ
## 15 I15 22 1 87.6 189 SÍ
## 16 I16 21 1 93.4 167 SÍ
## 17 I17 25 1 65.4 182 NO
## 18 I18 26 2 73.7 179 NO
## 19 I19 24 2 85.1 165 SÍ
## 20 I20 21 2 61.2 158 SÍ
## 21 I21 25 1 54.8 183 SÍ
## 22 I22 27 2 103.4 184 NO
## 23 I23 26 1 65.8 189 SÍ
## 24 I24 22 1 71.7 166 NO
## 25 I25 29 2 85.0 175 SÍ
Con data.frame() reunimos todos los vectores anteriores
en una única estructura. Cada fila corresponde a uno de los 25 registros
y cada columna a una de las variables.
En este apartado queremos quedarnos únicamente con las personas cuya edad sea superior a 22 años.
Para ello utilizamos subset() e indicamos la condición
Edad > 22.
# Seleccionamos los registros con una edad superior a 22 años
selec1 <- subset(Trat_Pulmon, Edad > 22)
# Mostramos el resultado
selec1
## Identificador Edad Sexo Peso Alt Fuma
## 1 I1 23 1 76.5 165 SÍ
## 2 I2 24 2 81.2 154 NO
## 5 I5 23 1 67.3 164 NO
## 6 I6 25 2 78.6 175 NO
## 7 I7 26 2 67.9 182 NO
## 8 I8 24 2 100.2 165 SÍ
## 11 I11 23 1 65.4 158 NO
## 12 I12 25 2 67.5 183 NO
## 13 I13 26 2 87.4 184 SÍ
## 14 I14 24 2 99.7 164 SÍ
## 17 I17 25 1 65.4 182 NO
## 18 I18 26 2 73.7 179 NO
## 19 I19 24 2 85.1 165 SÍ
## 21 I21 25 1 54.8 183 SÍ
## 22 I22 27 2 103.4 184 NO
## 23 I23 26 1 65.8 189 SÍ
## 25 I25 29 2 85.0 175 SÍ
El operador > significa “mayor que”, por lo que se
conservan únicamente las filas en las que Edad supera los
22 años. Este es el mismo procedimiento utilizado en la solución del
LAB. 【2-060744】
Ahora queremos acceder a una posición concreta del
data.frame: la fila 3 y la columna 4.
En R utilizamos la estructura [fila, columna]. Por
tanto:
# Seleccionamos el elemento de la fila 3 y la columna 4
selec2 <- Trat_Pulmon[3, 4]
# Mostramos el resultado
selec2
## [1] 79.3
La columna 4 corresponde a Peso, por lo que estamos
obteniendo el peso del tercer registro.
El resultado es:
79,3
La solución oficial utiliza también Trat_Pulmon[3, 4] y
obtiene 79,3. 【2-060744】
AltPor último, seleccionamos las filas correspondientes a edades
inferiores a 27 años y, al mismo tiempo, eliminamos la columna
Alt.
Volvemos a utilizar subset(). La condición
Edad < 27 selecciona las filas y
select = -c(Alt) indica que no queremos incluir la columna
Alt.
# Seleccionamos edades menores de 27 años y eliminamos la columna Alt
selec3 <- subset(Trat_Pulmon,Edad < 27, select = -c(Alt))
# Mostramos el resultado
selec3
## Identificador Edad Sexo Peso Fuma
## 1 I1 23 1 76.5 SÍ
## 2 I2 24 2 81.2 NO
## 3 I3 21 1 79.3 SÍ
## 4 I4 22 1 59.5 SÍ
## 5 I5 23 1 67.3 NO
## 6 I6 25 2 78.6 NO
## 7 I7 26 2 67.9 NO
## 8 I8 24 2 100.2 SÍ
## 9 I9 21 1 97.8 SÍ
## 10 I10 22 2 56.4 SÍ
## 11 I11 23 1 65.4 NO
## 12 I12 25 2 67.5 NO
## 13 I13 26 2 87.4 SÍ
## 14 I14 24 2 99.7 SÍ
## 15 I15 22 1 87.6 SÍ
## 16 I16 21 1 93.4 SÍ
## 17 I17 25 1 65.4 NO
## 18 I18 26 2 73.7 NO
## 19 I19 24 2 85.1 SÍ
## 20 I20 21 2 61.2 SÍ
## 21 I21 25 1 54.8 SÍ
## 23 I23 26 1 65.8 SÍ
## 24 I24 22 1 71.7 NO
En este caso combinamos dos operaciones en una sola instrucción:
primero filtramos los registros por edad y después excluimos la variable
Alt.
Así obtenemos un nuevo conjunto que mantiene
Identificador, Edad, Sexo,
Peso y Fuma, pero no incluye la altura.
ChickWeightEn este ejercicio vamos a trabajar con el conjunto de datos
ChickWeight, que está incluido en el paquete
datasets. Primero cargamos los datos y mostramos los
primeros registros para ver las variables que contiene.
# Cargamos el paquete datasets
library(datasets)
# Activamos el conjunto de datos ChickWeight
data("ChickWeight")
# Mostramos los primeros registros
head(ChickWeight)
## weight Time Chick Diet
## 1 42 0 1 1
## 2 51 2 1 1
## 3 59 4 1 1
## 4 64 6 1 1
## 5 76 8 1 1
## 6 93 10 1 1
Una vez que hemos visto las variables disponibles, hacemos los dos gráficos que pide el ejercicio.
weightPrimero representamos la variable weight mediante
plot(). Siguiendo la solución del LAB, utilizamos el color
blues9.
# Representamos los valores de weight
plot(ChickWeight$weight,
col = blues9,
main = "Gráfico 1")
Con este gráfico podemos observar cómo varían los valores de
weight entre las distintas observaciones del conjunto de
datos. Cada punto corresponde a un valor registrado de esta
variable.
TimePara la variable Time utilizamos boxplot(),
que nos permite observar de una forma resumida cómo se distribuyen sus
valores.
# Representamos la distribución de Time mediante un gráfico de caja
boxplot(ChickWeight$Time,
col = "yellow",
main = "Gráfico 2")
El gráfico de caja nos permite ver la distribución de
Time, incluyendo su posición central y la dispersión de los
valores.
En este ejercicio hemos utilizado dos formas diferentes de
representar variables numéricas. Con plot() observamos los
valores individuales de weight, mientras que con
boxplot() obtenemos un resumen gráfico de la distribución
de Time.
En este ejercicio volvemos a trabajar con el conjunto de datos
anorexia. En primer lugar, vamos a calcular la diferencia
entre el peso después del tratamiento (Postwt) y el peso
inicial (Prewt) para cada observación.
Como ya hemos utilizado anorexia anteriormente,
conocemos las variables que contiene. Calculamos la diferencia restando
Prewt a Postwt y guardamos el resultado en un
nuevo vector llamado post_pre_v.
# Calculamos la diferencia entre el peso posterior y el peso inicial
post_pre_v <- anorexia$Postwt - anorexia$Prewt
# Mostramos el vector obtenido
post_pre_v
## [1] -0.5 -9.3 -5.4 12.3 -2.0 -10.2 -12.2 11.6 -7.1 6.2 -0.2 -9.2
## [13] 8.3 3.3 11.3 0.0 -1.0 -10.6 -4.6 -6.7 2.8 0.3 1.8 3.7
## [25] 15.9 -10.2 1.7 0.7 -0.1 -0.7 -3.5 14.9 3.5 17.1 -7.6 1.6
## [37] 11.7 6.1 1.1 -4.0 20.9 -9.1 2.1 -1.4 1.4 -0.3 -3.7 -0.8
## [49] 2.4 12.6 1.9 3.9 0.1 15.4 -0.7 11.4 11.0 5.5 9.4 13.6
## [61] -2.9 -0.1 7.4 21.5 -5.3 -3.8 13.4 13.1 9.0 3.9 5.7 10.7
La operación se realiza elemento a elemento. Por tanto, cada valor de
post_pre_v corresponde a la diferencia de peso de una
observación.
Un valor positivo indica que Postwt es mayor que
Prewt, mientras que un valor negativo indica que
Postwt es menor que Prewt.
Ahora añadimos el vector que acabamos de calcular al conjunto de
datos anorexia. Para no modificar directamente el conjunto
original, creamos un nuevo data.frame llamado
anorexia_treat_df.
# Añadimos la diferencia de peso al conjunto de datos anorexia
anorexia_treat_df <- data.frame(anorexia, post_pre_v)
# Mostramos los primeros registros
head(anorexia_treat_df)
## Treat Prewt Postwt post_pre_v
## 1 Cont 80.7 80.2 -0.5
## 2 Cont 89.4 80.1 -9.3
## 3 Cont 91.8 86.4 -5.4
## 4 Cont 74.0 86.3 12.3
## 5 Cont 78.1 76.1 -2.0
## 6 Cont 88.3 78.1 -10.2
Ahora tenemos las tres variables originales, Treat,
Prewt y Postwt, junto con la nueva variable
post_pre_v.
Por último, utilizamos subset() para seleccionar las
observaciones del grupo Cont en las que la diferencia de
peso es mayor que 0.
# Seleccionamos el grupo Cont con una diferencia de peso positiva
anorexia_treat_C_df <- subset(anorexia_treat_df, Treat == "Cont" & post_pre_v > 0)
# Mostramos los primeros registros seleccionados
head(anorexia_treat_C_df)
## Treat Prewt Postwt post_pre_v
## 4 Cont 74.0 86.3 12.3
## 8 Cont 75.1 86.7 11.6
## 10 Cont 78.4 84.6 6.2
## 13 Cont 81.3 89.6 8.3
## 14 Cont 78.1 81.4 3.3
## 15 Cont 70.5 81.8 11.3
En este caso utilizamos dos condiciones al mismo tiempo:
Treat == "Cont" selecciona únicamente las
observaciones del grupo Cont.
post_pre_v > 0 selecciona aquellas en las que el
peso posterior es mayor que el peso inicial
El operador & indica que las dos condiciones
tienen que cumplirse a la vez.
De esta manera obtenemos un nuevo conjunto que contiene únicamente los registros que cumplen ambas condiciones.
Para este ejercicio me he registrado en RPubs y he consultado algunos ejemplos de documentos realizados con R Markdown.
Al revisar estos ejemplos he podido observar cómo se pueden combinar en un mismo documento el texto explicativo, los bloques de código y los resultados obtenidos en R. También aparecen diferentes formas de organizar los apartados y de presentar tablas y gráficos.
Después de realizar los ejercicios de este LAB, me ha resultado más fácil entender cómo están estructurados estos documentos, ya que durante el laboratorio hemos trabajado con estos mismos elementos.
En este caso práctico vamos a crear un conjunto de datos con 30 observaciones y trabajar con él utilizando algunas de las funciones que hemos aprendido durante el LAB.
Vamos a utilizar las variables Id, alt,
peso, edad, genero y
trat. Los datos son inventados únicamente para realizar el
ejercicio.
Empezamos creando las seis variables. Para genero
utilizamos los valores 1 y 2, con 15 observaciones de cada grupo. En
trat utilizamos tres tratamientos diferentes: A, B y C.
# Creamos un identificador para las 30 observaciones
Id <- 1:30
# Introducimos las alturas en centímetros
alt <- c(144,150,150,159,153,156,157,181,153,158,142,137,138,156,194,165,116,166,165,174,169,200,172,117,167,158,161,170,169,147)
# Introducimos los pesos en kg
peso <- c(75,95,95,65,98,101,100,63,98,77,92,83,83,101,58,110,65,100,108,122,114,90,117,62,112,89,106,85,111,60)
# Introducimos las edades
edad <- c(85,73,73,34,71,86,63,86,70,69,70,64,46,84,45,61,60,54,72,77,91,92,62,45,77,57,73,54,67,69)
# Creamos los dos grupos de genero
genero <- rep(c(1, 2), 15)
# Introducimos los tres tratamientos
trat <- rep(c("A", "B", "C"), 10)
# Reunimos todas las variables en un único data frame
datos_invent <- data.frame(Id, alt, peso, edad, genero, trat)
# Mostramos los primeros registros
head(datos_invent)
## Id alt peso edad genero trat
## 1 1 144 75 85 1 A
## 2 2 150 95 73 2 B
## 3 3 150 95 73 1 C
## 4 4 159 65 34 2 A
## 5 5 153 98 71 1 B
## 6 6 156 101 86 2 C
Con data.frame() reunimos los diferentes vectores en un
único conjunto de datos. Cada fila corresponde a una observación y cada
columna representa una de las variables.
Para comprobar que hemos creado correctamente las 30 observaciones, podemos consultar las dimensiones:
# Comprobamos el número de filas y columnas
dim(datos_invent)
## [1] 30 6
# Comprobamos la estructura del conjunto de datos
str(datos_invent)
## 'data.frame': 30 obs. of 6 variables:
## $ Id : int 1 2 3 4 5 6 7 8 9 10 ...
## $ alt : num 144 150 150 159 153 156 157 181 153 158 ...
## $ peso : num 75 95 95 65 98 101 100 63 98 77 ...
## $ edad : num 85 73 73 34 71 86 63 86 70 69 ...
## $ genero: num 1 2 1 2 1 2 1 2 1 2 ...
## $ trat : chr "A" "B" "C" "A" ...
dim() nos permite comprobar el número de filas y
columnas, mientras que str() muestra la estructura y el
tipo de cada variable.
Una vez creado el conjunto, utilizamos summary() para
obtener una primera descripción de sus variables.
# Obtenemos un resumen de las variables
summary(datos_invent)
## Id alt peso edad genero
## Min. : 1.00 Min. :116.0 Min. : 58.00 Min. :34.00 Min. :1.0
## 1st Qu.: 8.25 1st Qu.:150.0 1st Qu.: 78.50 1st Qu.:60.25 1st Qu.:1.0
## Median :15.50 Median :158.0 Median : 95.00 Median :69.50 Median :1.5
## Mean :15.50 Mean :158.1 Mean : 91.17 Mean :67.67 Mean :1.5
## 3rd Qu.:22.75 3rd Qu.:168.5 3rd Qu.:104.75 3rd Qu.:76.00 3rd Qu.:2.0
## Max. :30.00 Max. :200.0 Max. :122.00 Max. :92.00 Max. :2.0
## trat
## Length :30
## N.unique : 3
## N.blank : 0
## Min.nchar: 1
## Max.nchar: 1
##
Con summary() podemos observar diferentes valores
descriptivos de las variables numéricas, como el mínimo, la mediana, la
media y el máximo.
En el caso de trat, al tratarse de una variable de
texto, summary() muestra información sobre su estructura en
lugar de calcular estadísticos numéricos.
Ahora vamos a crear una nueva variable calculando el índice de masa corporal (IMC).
Utilizamos la fórmula:
IMC = peso / altura²
Como alt está expresada en centímetros, primero tenemos
que dividirla entre 100 para obtener la altura en metros.
# Calculamos el IMC de cada observación
IMC <- datos_invent$peso / (datos_invent$alt / 100)^2
# Mostramos los valores obtenidos
IMC
## [1] 36.16898 42.22222 42.22222 25.71101 41.86424 41.50230 40.56960 19.23018
## [9] 41.86424 30.84442 45.62587 44.22186 43.58328 41.50230 15.41078 40.40404
## [17] 48.30559 36.28974 39.66942 40.29594 39.91457 22.50000 39.54840 45.29184
## [25] 40.15920 35.65134 40.89348 29.41176 38.86419 27.76621
La operación se realiza para cada una de las 30 observaciones.
A continuación añadimos el IMC al conjunto de datos original y
guardamos el resultado en un nuevo objeto llamado
dataIMC.
# Añadimos el IMC al conjunto de datos
dataIMC <- data.frame(datos_invent, IMC)
# Mostramos los primeros registros
head(dataIMC)
## Id alt peso edad genero trat IMC
## 1 1 144 75 85 1 A 36.16898
## 2 2 150 95 73 2 B 42.22222
## 3 3 150 95 73 1 C 42.22222
## 4 4 159 65 34 2 A 25.71101
## 5 5 153 98 71 1 B 41.86424
## 6 6 156 101 86 2 C 41.50230
Ahora nuestro conjunto contiene una nueva columna llamada
IMC junto con las seis variables originales.
Este procedimiento sigue la misma estructura de la solución del LAB,
que calcula el IMC mediante peso / (alt/100)^2 y después
utiliza data.frame() para incorporarlo a los datos.
【1-11f6ec】
generoEn el siguiente paso vamos a dividir el conjunto de datos según la
variable genero.
Primero seleccionamos las observaciones con genero == 1
mediante subset() y las guardamos en
Df_Mujeres.
# Seleccionamos las observaciones con genero igual a 1
Df_Mujeres <- subset(dataIMC,genero == 1)
# Mostramos el resultado
Df_Mujeres
## Id alt peso edad genero trat IMC
## 1 1 144 75 85 1 A 36.16898
## 3 3 150 95 73 1 C 42.22222
## 5 5 153 98 71 1 B 41.86424
## 7 7 157 100 63 1 A 40.56960
## 9 9 153 98 70 1 C 41.86424
## 11 11 142 92 70 1 B 45.62587
## 13 13 138 83 46 1 A 43.58328
## 15 15 194 58 45 1 C 15.41078
## 17 17 116 65 60 1 B 48.30559
## 19 19 165 108 72 1 A 39.66942
## 21 21 169 114 91 1 C 39.91457
## 23 23 172 117 62 1 B 39.54840
## 25 25 167 112 77 1 A 40.15920
## 27 27 161 106 73 1 C 40.89348
## 29 29 169 111 67 1 B 38.86419
Después hacemos lo mismo con las observaciones correspondientes a
genero == 2 y las guardamos en Df_Hombres.
# Seleccionamos las observaciones con genero igual a 2
Df_Hombres <- subset(dataIMC,genero == 2)
# Mostramos el resultado
Df_Hombres
## Id alt peso edad genero trat IMC
## 2 2 150 95 73 2 B 42.22222
## 4 4 159 65 34 2 A 25.71101
## 6 6 156 101 86 2 C 41.50230
## 8 8 181 63 86 2 B 19.23018
## 10 10 158 77 69 2 A 30.84442
## 12 12 137 83 64 2 C 44.22186
## 14 14 156 101 84 2 B 41.50230
## 16 16 165 110 61 2 A 40.40404
## 18 18 166 100 54 2 C 36.28974
## 20 20 174 122 77 2 B 40.29594
## 22 22 200 90 92 2 A 22.50000
## 24 24 117 62 45 2 C 45.29184
## 26 26 158 89 57 2 B 35.65134
## 28 28 170 85 54 2 A 29.41176
## 30 30 147 60 69 2 C 27.76621
Con subset() podemos seleccionar únicamente las filas
que cumplen la condición indicada. De esta forma hemos dividido el
conjunto original en dos data frames.
Podemos comprobar cuántas observaciones contiene cada uno:
# Comprobamos las dimensiones de los dos data frames
dim(Df_Mujeres)
## [1] 15 7
dim(Df_Hombres)
## [1] 15 7
Como hemos creado 15 observaciones para cada valor de
genero, debemos obtener 15 filas en cada conjunto.
Por último, volvemos a unir Df_Hombres y
Df_Mujeres.
Para ello utilizamos rbind(), que permite unir dos data
frames por filas, siempre que tengan la misma estructura.
# Volvemos a unir los dos data frames
Df_Todo <- rbind(Df_Hombres, Df_Mujeres)
# Mostramos el resultado
Df_Todo
## Id alt peso edad genero trat IMC
## 2 2 150 95 73 2 B 42.22222
## 4 4 159 65 34 2 A 25.71101
## 6 6 156 101 86 2 C 41.50230
## 8 8 181 63 86 2 B 19.23018
## 10 10 158 77 69 2 A 30.84442
## 12 12 137 83 64 2 C 44.22186
## 14 14 156 101 84 2 B 41.50230
## 16 16 165 110 61 2 A 40.40404
## 18 18 166 100 54 2 C 36.28974
## 20 20 174 122 77 2 B 40.29594
## 22 22 200 90 92 2 A 22.50000
## 24 24 117 62 45 2 C 45.29184
## 26 26 158 89 57 2 B 35.65134
## 28 28 170 85 54 2 A 29.41176
## 30 30 147 60 69 2 C 27.76621
## 1 1 144 75 85 1 A 36.16898
## 3 3 150 95 73 1 C 42.22222
## 5 5 153 98 71 1 B 41.86424
## 7 7 157 100 63 1 A 40.56960
## 9 9 153 98 70 1 C 41.86424
## 11 11 142 92 70 1 B 45.62587
## 13 13 138 83 46 1 A 43.58328
## 15 15 194 58 45 1 C 15.41078
## 17 17 116 65 60 1 B 48.30559
## 19 19 165 108 72 1 A 39.66942
## 21 21 169 114 91 1 C 39.91457
## 23 23 172 117 62 1 B 39.54840
## 25 25 167 112 77 1 A 40.15920
## 27 27 161 106 73 1 C 40.89348
## 29 29 169 111 67 1 B 38.86419
Finalmente comprobamos sus dimensiones:
# Comprobamos las dimensiones del conjunto final
dim(Df_Todo)
## [1] 30 7
Al volver a unir los dos grupos obtenemos de nuevo un conjunto formado por las 30 observaciones.
Con este caso práctico hemos aplicado de forma conjunta varias de las
herramientas vistas durante el LAB: creación de vectores y data frames,
consulta de la estructura de los datos, cálculo de una nueva variable,
selección de observaciones mediante subset() y unión de
conjuntos mediante rbind().