una carpeta Ejercicio_1
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.
en la carpeta cliqueando sobre este archivo Ejercicios_1.Rmd mismo.
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.
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():
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 es una lista de data frames.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
Rrownames(): Obtiene o establece los nombres de las
filascolnames(): Obtiene o establece los nombres de las
columnasescribiendo 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:
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" ...
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.
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.
strsplit(x, split) donde
x es el vector de caracteres a dividir y split
es el separador (el guion “-”).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"
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.
lapply(X, FUN) donde
X es la lista y FUN es la función a
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.
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
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 ...
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" ...
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.
match(x, table) donde
x son los valores a buscar y table es donde se
buscan.NA.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)
Metadatos:
El archivo contiene datos de 13 países de Sudamérica con las siguientes variables:
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)
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:
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)
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:
# 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")
con el comando knitr, guardar los archivos .Rmd y .html y enviar-los a sergio@camiz.it dentro del 4 de Abril a las 23:59.