1 Inicio

1.1 Construir

una carpeta Ejercicio_1

1.2 Bajar desde Paideia

el material relativo a Clase 1. Atención que los archivos .Rmd no se bajan, sino se abren y se necesita copiar y pegar el contenido en un archivo de texto, con extensión .Rmd.

1.3 Abrir Rstudio

en la carpeta cliqueando sobre este archivo Ejercicios_1.Rmd mismo.

2 Lectura de datos

2.1 Instalar paquetes

Para leer un archivo de tipo .ods se necesita el paquete readODS, los cuales ya fueron instalados:

Una vez instalado en el menu Help a la derecha buscar readODS, leer la Overview propuesta, luego abrir readODS::readODS-package y cliquear sobre el index al fundo.

2.2 leer el help de las funciones read_ods() y write_ods(),

La función read_ods() sirve para leer una hoja de un archivo con formato .ods o .fods y devolver su contenido como un data frame en R.

Parámetros principales de read_ods():

  • path: ruta o nombre del archivo que se desea leer.
  • sheet: nombre o número de la hoja que se quiere importar.
  • col_names: indica si la primera fila contiene los nombres de las columnas.
  • col_types: permite definir el tipo de dato de cada columna.
  • na: especifica qué valores deben considerarse como datos faltantes (NA).
  • skip: número de filas que se omiten antes de empezar la lectura.
  • range: permite leer solo un rango específico de celdas.
  • row_names: indica si la primera columna debe usarse como nombres de filas.
  • trim_ws: elimina espacios en blanco al inicio y al final de los textos.
  • n_max: define el número máximo de filas que se van a leer.

La función write_ods() sirve para escribir un data frame o una lista de data frames a un archivo con formato .ods o .fods.

Parámetros principales de write_ods():

  • x: data frame o lista de data frames que serán hojas en el archivo (f)ods. Si la lista tiene nombres, estos se usan como nombres de las hojas.
  • path: ruta al archivo (f)ods donde se escribirá.
  • sheet: nombre de la hoja; se ignora si x es una lista de data frames.
  • append: lógico, TRUE indica que x debe añadirse al archivo existente como una nueva hoja. Si una hoja con el mismo nombre existe, se lanza una excepción. Por defecto es FALSE.
  • update: lógico, TRUE indica que la hoja con sheet_name en el archivo existente debe actualizarse con el contenido de x. Si la hoja no existe, se lanza una excepción. Por defecto es FALSE.
  • row_names: lógico, TRUE indica que los nombres de filas de x deben incluirse en la hoja. Por defecto es FALSE.
  • col_names: lógico, TRUE indica que los nombres de columnas de x deben incluirse en la hoja. Por defecto es TRUE.
  • na_as_string: lógico, TRUE indica que los NAs se escriben como cadena de texto; FALSE indica que los NAs se escriben como celdas vacías.
  • padding: lógico, TRUE indica que la hoja se rellena con celdas vacías repetidas hasta el tamaño máximo (2^20 x 1024 o 2^20 x 16,384). Por defecto es FALSE.

2.3 leer el help de los comandos

head(), str(), rownames() y colnames(), anotando aquí brievemente su empleo.

Comandos útiles:

  • head(): Muestra las primeras 6 filas de un objeto (por defecto)
  • str(): Muestra la estructura interna de un objeto R
  • rownames(): Obtiene o establece los nombres de las filas
  • colnames(): Obtiene o establece los nombres de las columnas

2.4 Leer el archivo Eggsorg.ods

escribiendo aquí un resumen de la hoja Metadata donde se explican los datos.

Resumen de Metadata:

Estos datos reportan características de anidación y reproducción de 96 especies de aves de Gran Bretaña. Los datos fueron tomados por DataBank (1990) de Hoeher (1974) y Holden and Sharrock (1982) para construir una base de datos con fines tutoriales.

El conjunto de datos contiene 8 variables:

  • Family: Nominal. Familia de especies a la que pertenece.
  • Size: Numérico. Longitud del ave en cm.
  • Nesting ground: Multi-nominal. Sitios de anidación (hasta tres).
  • Eggs: Intervalo. Número de huevos.
  • Length: Numérico. Longitud del huevo en mm.
  • Width: Numérico. Ancho del huevo en mm.
  • Mass: Numérico. Peso del huevo en g.
  • Hatch: Intervalo. Tiempo de incubación en días.

colocar su contenido en eggs y mostrar su estructura (comando str).

eggs <- read_ods("Eggsorg.ods", sheet = "Data", as_tibble = FALSE)
str(eggs)
## 'data.frame':    96 obs. of  9 variables:
##  $ Name          : chr  "Barn owl" "Black cap" "Black redstaft" "Blackbird" ...
##  $ Family        : chr  "Owl" "Warbler" "Chat" "Thrush" ...
##  $ Size          : num  34 14 14 25 11.5 14.5 15 95 47 15 ...
##  $ Nesting ground: chr  "Hollow trees, barns" "Bushes, low trees" "Hales, crevices" "Trees, bushes" ...
##  $ Eggs          : chr  "4-7" "4-6" "5-6" "4-6" ...
##  $ Length        : num  39.2 19.6 19.4 28.6 15.4 19.5 20.2 85.7 43.5 19.3 ...
##  $ Width         : num  30.8 14.7 14.4 21 11.9 14.6 15.1 58.2 30.1 14.6 ...
##  $ Mass          : num  20.7 1.9 2 9 1.3 2.2 2.1 228 19 2.1 ...
##  $ Hatch         : chr  "30" "14-15" "13" "13-14" ...

2.5 Correr read_ods con la opción

as_tibble=FALSE y la lista de las variables, con el comando colnames().

eggs <- read_ods("Eggsorg.ods", sheet = "Data", as_tibble = FALSE)
colnames(eggs)
## [1] "Name"           "Family"         "Size"           "Nesting ground"
## [5] "Eggs"           "Length"         "Width"          "Mass"          
## [9] "Hatch"

Nóte-se que Eggs y Hatch son indicados a veces como intervalo, mientras Nesting ground es múltiple y se puede borrar en seguida.

3 Construir nuevas M_Eggs y M_Hatch

3.1 estudiar la función strsplit()

para extraer los dos valores del intervalo, tirando el “-” los dos valores (o uno si es solo) deberían estar en una lista compuesta de una lista de uno o dos valores). Comentar al comando.

Aquí se necesita tirar “-” y por cada observación hay un vector con mínimo y máximo en una lista.

Explicación de strsplit():

La función strsplit() divide una cadena de texto en partes usando un separador especificado.

  • Sintaxis: strsplit(x, split) donde x es el vector de caracteres a dividir y split es el separador (el guion “-”).
  • Resultado: Devuelve una lista donde cada elemento contiene un vector con las partes divididas.

Ejemplo con nuestros datos:

# Aplicar strsplit a Eggs y Hatch
eggs_split <- strsplit(as.character(eggs$Eggs), "-")
hatch_split <- strsplit(as.character(eggs$Hatch), "-")

# Mostrar primeros 5 resultados
print("Primeros 5 de Eggs:")
## [1] "Primeros 5 de Eggs:"
eggs_split[1:5]
## [[1]]
## [1] "4" "7"
## 
## [[2]]
## [1] "4" "6"
## 
## [[3]]
## [1] "5" "6"
## 
## [[4]]
## [1] "4" "6"
## 
## [[5]]
## [1] "10" "13"
print("Primeros 5 de Hatch:")
## [1] "Primeros 5 de Hatch:"
hatch_split[1:5]
## [[1]]
## [1] "30"
## 
## [[2]]
## [1] "14" "15"
## 
## [[3]]
## [1] "13"
## 
## [[4]]
## [1] "13" "14"
## 
## [[5]]
## [1] "13" "15"

3.2 estudiar la función lapply()

Explicación de lapply():

La función lapply() aplica una función a cada elemento de una lista y devuelve una lista con los resultados.

  • Sintaxis: lapply(X, FUN) donde X es la lista y FUN es la función a aplicar.
  • Uso combinado: Se puede aplicar lapply() directamente sobre el resultado de strsplit() para convertir los valores de texto a numéricos.

Ejemplo con nuestros datos:

# Aplicar strsplit y lapply juntos para Eggs
eggs_numeric <- lapply(strsplit(as.character(eggs$Eggs), "-"), as.numeric)

# Aplicar strsplit y lapply juntos para Hatch
hatch_numeric <- lapply(strsplit(as.character(eggs$Hatch), "-"), as.numeric)

# Mostrar primeros 5 resultados
print("Primeros 5 de Eggs (numérico):")
## [1] "Primeros 5 de Eggs (numérico):"
eggs_numeric[1:5]
## [[1]]
## [1] 4 7
## 
## [[2]]
## [1] 4 6
## 
## [[3]]
## [1] 5 6
## 
## [[4]]
## [1] 4 6
## 
## [[5]]
## [1] 10 13
print("Primeros 5 de Hatch (numérico):")
## [1] "Primeros 5 de Hatch (numérico):"
hatch_numeric[1:5]
## [[1]]
## [1] 30
## 
## [[2]]
## [1] 14 15
## 
## [[3]]
## [1] 13
## 
## [[4]]
## [1] 13 14
## 
## [[5]]
## [1] 13 15

Con lapply() transformamos cada vector de caracteres en un vector de números, manteniendo la estructura de lista.

3.3 aplicar estos comandos

a Eggs y Hatch y construir nuevas M_Eggs y M_Hatch eligiendo el máximo con max() por cada observación de las listas (max() tira el máximo de cada vector de la lista de observaciones: aquí se necesita emplear for (i in 1:n) max(lista[[i]]).

# Obtener número de observaciones
n <- nrow(eggs)

# Crear vectores vacíos para los máximos
M_Eggs <- numeric(n)
M_Hatch <- numeric(n)

# Extraer el máximo de cada observación con un for
for (i in 1:n) {
  M_Eggs[i] <- max(eggs_numeric[[i]], na.rm = TRUE)
  M_Hatch[i] <- max(hatch_numeric[[i]], na.rm = TRUE)
}

# Mostrar los primeros valores
head(M_Eggs)
## [1]  7  6  6  6 13  6
head(M_Hatch)
## [1] 30 15 13 14 15 13

3.4 mostrar M_Eggs y M_Hatch

incluir en eggs en lugar de Eggs y Hatch y tirar Nesting ground, formando new_eggs. No olvidar los nombres de las filas!

# Mostrar los valores de M_Eggs y M_Hatch
head(M_Eggs)
## [1]  7  6  6  6 13  6
head(M_Hatch)
## [1] 30 15 13 14 15 13
# Crear new_eggs a partir de eggs
new_eggs <- eggs

# Agregar las nuevas columnas M_Eggs y M_Hatch
new_eggs$M_Eggs <- M_Eggs
new_eggs$M_Hatch <- M_Hatch

# Eliminar las columnas antiguas Eggs, Hatch y Nesting ground
new_eggs$Eggs <- NULL
new_eggs$Hatch <- NULL
new_eggs$`Nesting ground` <- NULL

# Asignar nombres de filas usando Name (que es único)
rownames(new_eggs) <- eggs$`Name                   `

# Mostrar la estructura del nuevo data frame
head(new_eggs)
##             Name  Family Size Length Width Mass M_Eggs M_Hatch
## 1       Barn owl     Owl 34.0   39.2  30.8 20.7      7      30
## 2      Black cap Warbler 14.0   19.6  14.7  1.9      6      15
## 3 Black redstaft    Chat 14.0   19.4  14.4  2.0      6      13
## 4      Blackbird  Thrush 25.0   28.6  21.0  9.0      6      14
## 5       Blue tit     Tit 11.5   15.4  11.9  1.3     13      15
## 6      Brambling   Finch 14.5   19.5  14.6  2.2      6      13
str(new_eggs)
## 'data.frame':    96 obs. of  8 variables:
##  $ Name   : chr  "Barn owl" "Black cap" "Black redstaft" "Blackbird" ...
##  $ Family : chr  "Owl" "Warbler" "Chat" "Thrush" ...
##  $ Size   : num  34 14 14 25 11.5 14.5 15 95 47 15 ...
##  $ Length : num  39.2 19.6 19.4 28.6 15.4 19.5 20.2 85.7 43.5 19.3 ...
##  $ Width  : num  30.8 14.7 14.4 21 11.9 14.6 15.1 58.2 30.1 14.6 ...
##  $ Mass   : num  20.7 1.9 2 9 1.3 2.2 2.1 228 19 2.1 ...
##  $ M_Eggs : num  7 6 6 6 13 6 5 6 6 6 ...
##  $ M_Hatch: num  30 15 13 14 15 13 13 30 19 13 ...

3.5 Incluir el orden taxonómico

Del archivo Eggsorg.ods, colgar la hoja “Orders” en un data.frame.

orders <- read_ods("Eggsorg.ods", sheet = "Orders", as_tibble = FALSE)
head(orders)
##   Common Name Taxonomic Family Taxonomic Order
## 1         Owl        Strigidae    Strigiformes
## 2     Warbler        Sylviidae   Passeriformes
## 3        Chat     Muscicapidae   Passeriformes
## 4      Thrush         Turdidae   Passeriformes
## 5         Tit          Paridae   Passeriformes
## 6       Finch     Fringillidae   Passeriformes
str(orders)
## 'data.frame':    16 obs. of  3 variables:
##  $ Common Name     : chr  "Owl" "Warbler" "Chat" "Thrush" ...
##  $ Taxonomic Family: chr  "Strigidae" "Sylviidae" "Muscicapidae" "Turdidae" ...
##  $ Taxonomic Order : chr  "Strigiformes" "Passeriformes" "Passeriformes" "Passeriformes" ...

3.6 estudiar aquí la función match()

Explicación de match():

La función match() devuelve un vector con las posiciones (índices) de las primeras coincidencias de su primer argumento en su segundo argumento.

  • Sintaxis: match(x, table) donde x son los valores a buscar y table es donde se buscan.
  • Resultado: Devuelve las posiciones donde se encuentran los valores. Si no hay coincidencia, devuelve NA.

3.7 construir el índice

que asocia a cada familia en new_eggs la misma familia en orders y luego emplearlo tomando el order correspondiente en orders, así construyendo la nueva variable new_eggs$Order y guardar todo en Eggs.ods:

# Crear el índice que asocia cada familia de new_eggs con orders
idx <- match(new_eggs$`Family       `, orders$Family)

# Agregar la columna Order a new_eggs usando el índice
new_eggs$Order <- orders$Order[idx]

# Mostrar resultado
head(new_eggs)
##             Name  Family Size Length Width Mass M_Eggs M_Hatch
## 1       Barn owl     Owl 34.0   39.2  30.8 20.7      7      30
## 2      Black cap Warbler 14.0   19.6  14.7  1.9      6      15
## 3 Black redstaft    Chat 14.0   19.4  14.4  2.0      6      13
## 4      Blackbird  Thrush 25.0   28.6  21.0  9.0      6      14
## 5       Blue tit     Tit 11.5   15.4  11.9  1.3     13      15
## 6      Brambling   Finch 14.5   19.5  14.6  2.2      6      13
# Guardar en archivo Eggs.ods
write_ods(new_eggs, path = "Eggs.ods", sheet = "Data", row_names = TRUE)

4 Regresiones de ejemplo

4.1 Archivo SudAmerica.ods

4.1.1 Leer el archivo SudAmerica.ods

Metadatos:

El archivo contiene datos de 13 países de Sudamérica con las siguientes variables:

  • País: Nombre del país sudamericano
  • Tajo_urbano: Porcentaje de población urbana (%)
  • IDH: Índice de Desarrollo Humano (escala de 0 a 1)

El objetivo es analizar la relación entre la urbanización y el desarrollo humano en países sudamericanos.

Hacer la regresión indicada en la clase:

# Leer el archivo
SudAmerica <- read_ods("SudAmerica.ods", sheet = 1, as_tibble = FALSE)
## New names:
## • `` -> `...1`
# Ver estructura
str(SudAmerica)
## 'data.frame':    13 obs. of  3 variables:
##  $ ...1       : chr  "Argentina" "Bolivia" "Brasil" "Chile" ...
##  $ Tajo_urbano: num  86 51 75 86 70 56 35 54 48 70 ...
##  $ IDH        : num  0.833 0.394 0.739 0.863 0.758 0.641 0.539 0.731 0.637 0.6 ...
head(SudAmerica)
##        ...1 Tajo_urbano   IDH
## 1 Argentina          86 0.833
## 2   Bolivia          51 0.394
## 3    Brasil          75 0.739
## 4     Chile          86 0.863
## 5  Colombia          70 0.758
## 6   Ecuador          56 0.641
# Renombrar la primera columna
colnames(SudAmerica)[1] <- "Pais"

# Regresión lineal: IDH en función de Tajo_urbano
modelo_sa <- lm(IDH ~ Tajo_urbano, data = SudAmerica)
summary(modelo_sa)
## 
## Call:
## lm(formula = IDH ~ Tajo_urbano, data = SudAmerica)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.22772 -0.01044  0.01240  0.03322  0.14512 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)   
## (Intercept) 0.318545   0.108546   2.935  0.01358 * 
## Tajo_urbano 0.005945   0.001609   3.694  0.00354 **
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.098 on 11 degrees of freedom
## Multiple R-squared:  0.5537, Adjusted R-squared:  0.5131 
## F-statistic: 13.65 on 1 and 11 DF,  p-value: 0.003537
# Gráficos diagnósticos
par(mfrow = c(2, 2))
plot(modelo_sa)

# Gráfico de dispersión con línea de regresión
par(mfrow = c(1, 1))
plot(SudAmerica$Tajo_urbano, SudAmerica$IDH,
     xlab = "Porcentaje Urbano (%)", 
     ylab = "Índice de Desarrollo Humano",
     main = "Relación entre Urbanización e IDH en Sudamérica",
     pch = 19, col = "blue")
abline(modelo_sa, col = "red", lwd = 2)
text(SudAmerica$Tajo_urbano, SudAmerica$IDH, 
     labels = SudAmerica$Pais, pos = 3, cex = 0.7)

4.1.2 correr la regresión del archivo Baseball.ods

considerando como criterio la variable WinningPerc, Porcentaje de gano y como regresor BattingAvg, Promedio de bateo.

Escribir antes el contenido de los metadatos, correr la regresión, los gráficos y comentar los resultados de manera análoga al caso precedente.

Metadatos:

El archivo contiene datos de 14 equipos de béisbol de la Liga Americana con las siguientes variables:

  • Equipo: Nombre del equipo de béisbol
  • BattingAvg: Promedio de bateo del equipo (proporción de hits sobre turnos al bate)
  • WinningPerc: Porcentaje de victorias del equipo en la temporada

El objetivo es analizar si existe una relación entre el promedio de bateo de un equipo y su porcentaje de victorias.

# Leer el archivo
baseball <- read_ods("Baseball.ods", sheet = 1, as_tibble = FALSE)
## New names:
## • `` -> `...1`
# Ver estructura
str(baseball)
## 'data.frame':    14 obs. of  3 variables:
##  $ ...1       : chr  "Baltimore" "Boston" "California" "Chicago" ...
##  $ BattingAvg : num  0.266 0.269 0.256 0.246 0.271 0.259 0.25 0.271 0.274 0.268 ...
##  $ WinningPerc: num  0.574 0.661 0.508 0.41 0.5 0.467 0.508 0.525 0.403 0.587 ...
head(baseball)
##         ...1 BattingAvg WinningPerc
## 1  Baltimore      0.266       0.574
## 2     Boston      0.269       0.661
## 3 California      0.256       0.508
## 4    Chicago      0.246       0.410
## 5  Cleveland      0.271       0.500
## 6    Detroit      0.259       0.467
# Renombrar la primera columna
colnames(baseball)[1] <- "Equipo"

# Regresión lineal: WinningPerc en función de BattingAvg
modelo_baseball <- lm(WinningPerc ~ BattingAvg, data = baseball)
summary(modelo_baseball)
## 
## Call:
## lm(formula = WinningPerc ~ BattingAvg, data = baseball)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.14627 -0.03653 -0.01800  0.05004  0.13132 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)  
## (Intercept)  -0.5245     0.5154  -1.018   0.3289  
## BattingAvg    3.9189     1.9694   1.990   0.0699 .
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.07017 on 12 degrees of freedom
## Multiple R-squared:  0.2481, Adjusted R-squared:  0.1854 
## F-statistic: 3.959 on 1 and 12 DF,  p-value: 0.06989
# Gráficos diagnósticos
par(mfrow = c(2, 2))
plot(modelo_baseball)

# Gráfico de dispersión con línea de regresión
par(mfrow = c(1, 1))
plot(baseball$BattingAvg, baseball$WinningPerc,
     xlab = "Promedio de Bateo", 
     ylab = "Porcentaje de Victorias",
     main = "Relación entre Promedio de Bateo y Victorias",
     pch = 19, col = "blue")
abline(modelo_baseball, col = "red", lwd = 2)
text(baseball$BattingAvg, baseball$WinningPerc, 
     labels = baseball$Equipo, pos = 3, cex = 0.6)

4.1.3 Regresión múltiple

Empleando los datos Eggs correr una regresión múltiple intentando de explicar el peso de los huevos con las demás variables numéricas. Nóten que en la fórmula de lm() los regresores se “suman” colocando el “+” entre ellos.

Incluir los metadatos y intentar de comentar los resultados.

Metadatos:

Los datos contienen características de anidación y reproducción de 96 especies de aves de Gran Bretaña. Las variables numéricas incluyen:

  • Mass (variable dependiente): Peso del huevo en gramos
  • Length: Longitud del huevo en mm
  • Width: Ancho del huevo en mm
  • Size: Longitud del ave en cm
  • M_Eggs: Número máximo de huevos por nidada
  • M_Hatch: Tiempo máximo de incubación en días
# Limpiar nombres de columnas (quitar espacios)
colnames(new_eggs) <- trimws(colnames(new_eggs))

# Ver estructura de los datos
str(new_eggs)
## 'data.frame':    96 obs. of  8 variables:
##  $ Name   : chr  "Barn owl" "Black cap" "Black redstaft" "Blackbird" ...
##  $ Family : chr  "Owl" "Warbler" "Chat" "Thrush" ...
##  $ Size   : num  34 14 14 25 11.5 14.5 15 95 47 15 ...
##  $ Length : num  39.2 19.6 19.4 28.6 15.4 19.5 20.2 85.7 43.5 19.3 ...
##  $ Width  : num  30.8 14.7 14.4 21 11.9 14.6 15.1 58.2 30.1 14.6 ...
##  $ Mass   : num  20.7 1.9 2 9 1.3 2.2 2.1 228 19 2.1 ...
##  $ M_Eggs : num  7 6 6 6 13 6 5 6 6 6 ...
##  $ M_Hatch: num  30 15 13 14 15 13 13 30 19 13 ...
# Regresión múltiple: Mass explicado por las demás variables numéricas
modelo_eggs <- lm(Mass ~ Length + Width + Size + M_Eggs + M_Hatch, 
                  data = new_eggs)
summary(modelo_eggs)
## 
## Call:
## lm(formula = Mass ~ Length + Width + Size + M_Eggs + M_Hatch, 
##     data = new_eggs)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -27.220  -8.457   1.694   6.662 105.882 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -32.25145    6.63365  -4.862 4.91e-06 ***
## Length        1.70608    0.41413   4.120 8.41e-05 ***
## Width         0.02257    0.13836   0.163    0.871    
## Size          0.38793    0.30209   1.284    0.202    
## M_Eggs        1.10848    0.75860   1.461    0.147    
## M_Hatch      -1.22199    0.59227  -2.063    0.042 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 16.55 on 90 degrees of freedom
## Multiple R-squared:  0.775,  Adjusted R-squared:  0.7625 
## F-statistic: 62.01 on 5 and 90 DF,  p-value: < 2.2e-16
# Gráficos diagnósticos estándar
par(mfrow = c(2, 2))
plot(modelo_eggs)
## Warning in sqrt(crit * p * (1 - hh)/hh): Se han producido NaNs
## Warning in sqrt(crit * p * (1 - hh)/hh): Se han producido NaNs

# Gráfico de residuos vs valores ajustados
par(mfrow = c(1, 1))
plot(fitted(modelo_eggs), residuals(modelo_eggs),
     xlab = "Valores Ajustados", 
     ylab = "Residuos",
     main = "Residuos vs Valores Ajustados",
     pch = 19, col = "blue")
abline(h = 0, col = "red", lwd = 2, lty = 2)

# Histograma de residuos
hist(residuals(modelo_eggs), 
     main = "Distribución de Residuos",
     xlab = "Residuos",
     col = "lightblue",
     breaks = 20)

# Q-Q plot de residuos
qqnorm(residuals(modelo_eggs), pch = 19, col = "blue")
qqline(residuals(modelo_eggs), col = "red", lwd = 2)

# Matriz de correlaciones entre variables
variables_numericas <- new_eggs[, c("Mass", "Length", "Width", "Size", "M_Eggs", "M_Hatch")]
pairs(variables_numericas, main = "Matriz de Dispersión - Variables Numéricas", pch = 19, col = "blue")

5 Construir Ejercicio_1.html

con el comando knitr, guardar los archivos .Rmd y .html y enviar-los a dentro del 4 de Abril a las 23:59.