plot(iris)
Apéndice 2: Soluciones a ejercicios seleccionados
Hay muchas maneras de resolve los problemas propuestos a lo largo del libro. Las que se muestran en este apéndice no son las mejores en general; pero las respuestas propuestas para los problemas del capítulo 3, por ejemplo, están entre las mejores que cabe esperar de quien solo conozca el contenido de los capítulos 1, 2 y 3.
De hecho, muchos de los problemas están planteados directamente como meros ejercicios prácticos y aplicación casi inmediata del contenido que los circunda.
Solución al Ejercicio 1.1
Al hacer
se ven claramente patrones como los siguientes:
- Existen tres especies distintas.
- Existe una relación más o menos lineal entre la longitud y la anchura de los pétalos.
- Una de las especies tiene características muy distintas del resto, mientras que las otras dos son más parecidas entre sí.
Solución al Ejercicio 1.2
Entre otras cosas, tienen que quedar claras las dimensiones de la tabla y las características (numéricas, alfanuméricas, etc.) de las columnas. Para las columnas numéricas se obtiene una indicación del tamaño (o la distribución) de los valores.
Solución al Ejercicio 1.3
head(iris, 10)
Solución al Ejercicio 1.4
Las llamadas
summary(airquality)
dim(airquality)
colnames(airquality)
proporcionan la información requerida y
head(airquality, 13)
las 13 primeras filas.
Solución al Ejercicio 1.5
summary(attenu)
deja claro que la columna station
tiene 16 valores nulos.
Solución al Ejercicio 1.7
$Petal.Length > 4,] iris[iris
Solución al Ejercicio 1.8
$cyl < 6 & mtcars$gear == 4,] mtcars[mtcars
Solución al Ejercicio 1.9
<- airquality
mi_copia ls()
$temperatura <- mi_copia$temperatura
mi_copiahead(mi_copia) # por ejemplo
$temperatura <- NULL
mi_copiarm(mi_copia)
Solución al Ejercicio 1.10
<- CO2[(CO2$Treatment == "chilled") & (CO2$uptake > 15),]
tmp head(tmp, 10)
También se puede resolver en una sola línea. A veces hay que equilibrar concisión y legibilidad y eso depende frecuentemente del estilo y personalidad de cada cual.
Los paréntesis no son estrictamente necesarios —compruébalo—, pero no está de más añadirlos, por claridad.
Solución al Ejercicio 1.12
<- iris[order(iris$Species, iris$Petal.Length),] res
Solución al Ejercicio 1.13
Fue el 5 de mayo (ordena la tabla y examina el resultado).
Solución al Ejercicio 1.14
El día 11 (ordena la tabla después de filtrar y quedarte solo con el mes de junio).
Solución al Ejercicio 1.15
<- read.table("paro.csv", header = TRUE, sep = "\t") paro
Presta atención a cómo se indica que el separador es un tabulador. Por supuesto, dependiendo de cuál sea tu directorio de trabajo, tendrás que modificar o no la ruta a paro.csv
.
Solución al Ejercicio 1.16
El indicion más claro de que has indicado mal el separador del fichero es que la tabla resultante tiene una única columna en la que aparecen todos los datos apelotonados.
Solución al Ejercicio 1.18
<- read.table("https://datanalytics.com/uploads/datos_treemap.txt",
datos header = TRUE, sep = "\t")
Solución al Ejercicio 1.19
<- tempfile()
tmp_file download.file("https://datanalytics.com/uploads/datos_treemap.txt", tmp_file)
<- read.table(tmp_file, header = TRUE, sep = "\t") datos
En el código anterior, hemos usado tempfile
(consulta tempfile
) para crear un fichero en un directorio temporal en el que luego hemos descargado el fichero de internet. Finalmente, se ha leído como cualquier otro fichero.
El fichero permanecerá en el directorio temporal hasta ser borrado explícitamente o hasta que se cierre la sesión de R.
Solución al Ejercicio 1.24
Si tienes problemas con este ejercicio, consulta los ejemplos que aparecen en ?png
.
Solución al Ejercicio 1.27
plot(iris$Petal.Length, iris$Petal.Width)
El gráfico sugiere, al menos, dos cosas: una relación lineal entre las variables y la existencia de dos grupos diferenciados. ¿Crees que puedes diferenciarlos?
Solución al Ejercicio 1.31
La inspección del gráfico sugiere que, para identificar el outlier, se puede hacer:
$Species == 'setosa' & iris$Sepal.Width < 2.5,] iris[iris
Solución al Ejercicio 1.32
boxplot(airquality$Temp ~ airquality$Month)
Solución al Ejercicio 1.34
mean(airquality$Temp)
mean(airquality$Temp[airquality$Month == 5])
tail(airquality[order(airquality$Wind),], 1)
# o bien
which.max(airquality$Wind),] airquality[
Solución al Ejercicio 1.37
hist(airquality$Temp)
abline(v = mean(airquality$Temp), col = "red")
Solución al Ejercicio 1.38
<- read.csv("pisasci2006.csv")
pisa which(pisa$Country == "Spain")
$Country == "Spain",]
pisa[pisa
plot(pisa$Income, pisa$Overall)
$Income > .9 & pisa$Overall < 400,]
pisa[pisa
hist(pisa$Overall)
abline(v = pisa$Overall[pisa$Country == "Spain"], col = "red")
Solución al Ejercicio 2.1
1:nrow(iris)
Solución al Ejercicio 2.2
seq(1, 2, by = .1)
# o bien,
1 + 0:10 / 10
Solución al Ejercicio 2.3
c(1, 3, 5)] iris[,
Solución al Ejercicio 2.4
c(1:4, 100:104),] iris[
Solución al Ejercicio 2.5
c("Wind", "Temp")] airquality[,
Solución al Ejercicio 2.6
rep(1, 100),] iris[
Solución al Ejercicio 2.7
table(CO2$Type)
Solución al Ejercicio 2.9
<- 1:10
x 1:(length(x) - 2)] x[
Solución al Ejercicio 2.10
<- 1:10
x -1] - x[-length(x)]
x[
diff(x)
Solución al Ejercicio 2.11
<- iris
mi_iris colnames(mi_iris)[1:2] <- c("Longitud.Sepalo", "Anchura.Sepalo")
Solución al Ejercicio 2.12
sample(1:nrow(iris), 30),] iris[
Solución al Ejercicio 2.13
Hay varias maneras de resolver este problema. Por ejemplo,
<- sample(1:nrow(iris), 75)
indices <- iris[indices,]
parte_01 <- iris[-indices,] parte_02
Alternativamente,
<- iris[sample(nrow(iris)),]
tmp <- head(iris, 75)
parte_01 <- tail(iris, 75) parte_02
¿Se te ocurre alguna más?
Solución al Ejercicio 2.18
Muestra los casos más frecuentes (y sus respectivas frecuencias).
Solución al Ejercicio 2.22
<- 0:1e6
x <- (-1)^x / (2*x + 1)
x sum(x)
Solución al Ejercicio 2.24
<- function(x) exp(sum(log(x))) mi_prod
Solución al Ejercicio 2.26
tapply(airquality$Temp, airquality$Month, mean)
Solución al Ejercicio 2.27
tapply(airquality$Ozone, airquality$Month, mean, na.rm = T)
Solución al Ejercicio 2.28
tapply(mtcars$hp, mtcars$cyl, median)
Solución al Ejercicio 2.30
rep(letters, times = 26:1)
Solución al Ejercicio 2.31
<- rep(letters, times = 26:1)
reps <- names(tail(sort(table(reps)), 5))
frecuentes !reps %in% frecuentes] <- "otros" reps[
Solución al Ejercicio 2.32
<- rep(0, 1e6)
pop 1:1e5] <- 1
pop[<- sample(pop, 1000)
encuesta 100 * mean(encuesta)
Solución al Ejercicio 2.34
<- rep(0, 1e6)
pop 1:1e5] <- 1
pop[<- replicate(500, 100 * mean(sample(pop, 1000)))
encuestas hist(encuestas)
Solución al Ejercicio 3.1
wilcox.test(sleep$extra ~ sleep$group)
Solución al Ejercicio 3.3
<- lm(Ozone ~ Temp, data = airquality)
modelo plot(airquality$Temp, airquality$Ozone)
abline(modelo, col = "red")
Solución al Ejercicio 3.4
Para aplicar el test de proporciones se puede hacer lo siguiente:
<- as.data.frame(UCBAdmissions)
datos $Admit <- datos$Admit == "Admitted"
datos<- datos[datos$Gender == "Male",]
h <- datos[datos$Gender != "Male",]
m
<- sum(h$Freq[h$Admit])
h_a <- sum(m$Freq[m$Admit])
m_a
prop.test(c(h_a, m_a),
c(sum(h$Freq), sum(m$Freq)))
Los p-valores son idénticos, pero es engañoso: en ambos casos están en el límite inferior de lo que muestra R. Si el p-valor fuese mayor, se vería que —particularmente, si no se aplica la llamada _corrección de Yates— coinciden. Para más información, véase esto.
Solución al Ejercicio 4.3
La misma función que para vectores: c
.
Solución al Ejercicio 4.4
<- list(a1 = 2, a2 = 7)
a $a1 <- NULL a
Solución al Ejercicio 4.6
Una obtiene el elemento en cuestión. La otra, una lista que contiene a dicho elemento. Es la misma diferencia que hay entre un vaso con agua y el agua que contiene el vaso.
Solución al Ejercicio 4.7
<- list() a
Solución al Ejercicio 4.9
Es una lista con tres componentes, cada uno de los cuales es una tabla con cincuenta filas.
Solución al Ejercicio 4.10
sapply(tmp, dim)
lapply(tmp, dim)
Solución al Ejercicio 4.12
<- rep(letters[1:5], each = 30)
tmp <- sample(tmp)
tmp <- split(iris, tmp) res
Solución al Ejercicio 4.14
Porque cada elemento de la entrada puede partirse en un número desigual de bloques.
Solución al Ejercicio 4.15
<- list(a = 1:3, b = c("hola", "adiós"))
mi_lista
sum(mi_lista$a)
$b <- c(mi_lista$b, "hasta luego")
mi_listasapply(mi_lista, length)
$iris <- iris
mi_lista$a <- NULL mi_lista
Solución al Ejercicio 6.4
grep("[0-9]", colors(), value = TRUE)
grep("^yellow", colors(), value = TRUE)
grep("blue", colors(), value = TRUE)
gsub("[0-9]", "x", colors())
gsub("[0-9]+", "x", colors())
Solución al Ejercicio 6.5
$usd <- as.numeric(
paises_por_pibgsub(" ", "",
"Dólaresinter-nacionales"]])) paises_por_pib[[
Solución al Ejercicio 6.6
<- data.frame(
dat a = 1:3,
b = c("20,34", "1.345,42", "1.234.5678,90"))
$b <- gsub("\\.", "", dat$b)
dat$b <- gsub(",", ".", dat$b)
dat$b <- as.numeric(dat$b) dat
Solución al Ejercicio 6.7
<- c("ventas_20220522_zaragoza.csv",
ficheros "pedidos-firmes_20220422_soria.csv")
<- gsub(".csv", "", ficheros)
ficheros <- strsplit(ficheros, "_")
ficheros <- as.data.frame(do.call(rbind, ficheros))
ficheros colnames(ficheros) <- c("nombre", "fecha", "provincia")
$fecha <- as.Date(ficheros$fecha, "%Y%m%d") ficheros
Solución al Ejercicio 6.8
<- c("41°39'00''N","0°53'00''O")
coords
<- as.numeric(gsub("°.*", "", coords))
grados <- as.numeric(gsub(".*°([0-9]*)'.*", "\\1", coords))
minutos <- as.numeric(gsub(".*'([0-9]*)''.*", "\\1", coords))
segundos
<- grados + minutos / 60 + segundos / 3600 coords_dec
Solución al Ejercicio 7.1
wilcox.test(sleep$extra ~ sleep$group)
Solución al Ejercicio 7.1
wilcox.test(sleep$extra ~ sleep$group)
Solución al Ejercicio 7.1
wilcox.test(sleep$extra ~ sleep$group)
Solución al Ejercicio 7.1
wilcox.test(sleep$extra ~ sleep$group)
Solución al Ejercicio 7.1
wilcox.test(sleep$extra ~ sleep$group)
Solución al Ejercicio 7.1
wilcox.test(sleep$extra ~ sleep$group)
Solución al Ejercicio 7.1
wilcox.test(sleep$extra ~ sleep$group)
Solución al Ejercicio 7.1
wilcox.test(sleep$extra ~ sleep$group)
Solución al Ejercicio 7.1
wilcox.test(sleep$extra ~ sleep$group)
Solución al Ejercicio 7.1
wilcox.test(sleep$extra ~ sleep$group)
Solución al Ejercicio 7.1
wilcox.test(sleep$extra ~ sleep$group)
Solución al Ejercicio 7.1
wilcox.test(sleep$extra ~ sleep$group)
Solución al Ejercicio 7.1
wilcox.test(sleep$extra ~ sleep$group)