Domine un paradigma de programación central con el paquete purrr: para cada ____ haga ____.

checker <- function(label, user_code, check_code, envir_result, evaluate_result, …) { list(message = check_code, correct = TRUE, location = “append”) }

Iteración

Aquí hay un número. Puedes hacer muchas cosas con él, como esto:

  • Tomar el registro del número. Luego haga clic en Enviar respuesta.
log(1)
## [1] 0

Aquí hay muchos números. ¿Y si quieres hacer cosas con ellos? Avanzar:

  • Llevar la bitácora de cada uno. No te pongas elegante.
log(1)
## [1] 0
log(2)
## [1] 0.6931472
log(3)
## [1] 1.098612
log(4)
## [1] 1.386294
log(5)
## [1] 1.609438

Vectorización

Por lo general, no necesita repetirse cuando usa R. Casi todas las funciones en R están vectorizadas . Esto significa que si coloca sus valores en un vector y luego ejecuta una función en el vector, R aplicará la función de forma iterativa a cada uno de los valores.

  • Haga clic en Enviar respuesta para probarlo. Vale la pena ver al menos una vez!
numbers <- c(1, 2, 3, 4, 5)
log(numbers)
## [1] 0.0000000 0.6931472 1.0986123 1.3862944 1.6094379

No todas las funciones en R están vectorizadas, y las que están vectorizadas a menudo solo funcionan con vectores no recursivos .

¿Qué significa eso? Bueno, hay dos tipos de vectores en R:

  1. vectores no recursivos
  2. vectores recursivos

Veamos cada uno.

Vectores no recursivos

Los vectores no recursivos son generalmente lo que piensas cuando piensas en un vector. Cada elemento de un vector no recursivo es un valor único y todos los valores en un vector no recursivo son del mismo tipo.

Los ejemplos de vectores no recursivos en R incluyen:

  • vectores dobles (es decir, vectores numéricos)
  • vectores enteros
  • vectores de caracteres
  • vectores lógicos
  • factores
  • y así sucesivamente

Como viste con log() , casi todas las funciones en R están vectorizadas para trabajar con vectores no recursivos. Aquí, numbers es un vector no recursivo.

numbers <- c(1, 2, 3, 4, 5)
log(numbers)
## [1] 0.0000000 0.6931472 1.0986123 1.3862944 1.6094379

¿Qué pasa con los vectores recursivos?

Vectores recursivos

Un vector recursivo es un vector cuyos elementos individuales pueden ser cualquier cosa, incluso otros vectores, incluso otros vectores recursivos. De ahí el nombre.

Los vectores recursivos son tan especiales que R les da un nombre especial, listas . Puedes pensar en las listas como el pegamento que mantiene unido a R. R usa listas para crear marcos de datos, entornos, objetos modelo y más.

Pero, ¿las funciones R están vectorizadas para trabajar con listas?

NO SE PUDO EJECUTAR DEBIDO A QUE log(list1) NO SE ARGUMENTA PARA UNA FUNCION MATEMATICA

Casi ninguna función en R está vectorizada para trabajar con listas. Y puede ver por qué: las listas pueden contener diferentes tipos de objetos. Por ejemplo, la siguiente lista contiene tanto un número como un vector de caracteres.

chars <- c("a", "b", "c")
list2 <- list(1, chars)
list2
## [[1]]
## [1] 1
## 
## [[2]]
## [1] "a" "b" "c"

¿Qué tan probable es que una función R funcione tanto con 1 como con el vector c("a", "b", "c") ?

La mayoría de las funciones de R solo funcionan con un solo tipo de datos, por lo que sus autores se las arreglan para que manejen vectores no recursivos, pero no listas.

Vocabulario importante

Los vectores recursivos tienen un nombre cotidiano, listas, pero los vectores no recursivos no. La gente tiende a llamar a los vectores no recursivos vectores , pero eso no es muy preciso ya que los vectores recursivos también son vectores.

Para distinguir los vectores no recursivos de los vectores recursivos, me referiré a los vectores recursivos como listas ya los vectores no recursivos como vectores simples .

Es importante tener en cuenta que las listas son un tipo de vector. Entonces, si me ve decir vector en lugar de simple vector , me refiero a listas y vectores simples.

Ahora bien, ¿cómo se debe trabajar con las listas?

¿Qué debe hacer?

No te preocupes, no hay razón para volver a repetir las cosas a mano para las listas, aunque podrías hacerlo. ¿No podrías? Vamos a ver.

Puede extraer cada elemento de una lista con la sintaxis de corchetes [[i]] . Por ejemplo, lista2[[2]] extrae el segundo elemento de lista2 :

list2[[2]]
## [1] "a" "b" "c"
  • Termina el código a continuación para tomar el registro de cada valor en list1 . Luego haga clic en Enviar respuesta.
list1[[1]]
list1[[2]]
list1[[3]]
list1[[4]]
list1[[5]]

Purrr

Este manual básico le enseñará cómo resolver problemas de iteración con el paquete purrr. En particular, aprenderá a usar la familia de funciones de mapas y sus derivadas, como

  • map()
  • map_dbl()
  • map2()
  • pmap()
  • invoke_map() y más

Otros enfoques

Pero hay otras formas de resolver problemas de iteración en R. Podrías usar:

  • para bucles
  • la familia de funciones lapply
  • funciones específicas de la situación como rowwise() y transpose()

Entonces, ¿por qué aprender a usar el paquete purrr?

Porque purrr?

Para concretar la discusión, comencemos con un ejemplo. Así es como usaría purrr para calcular la media de cada elemento de una lista llamada x :

map(x, mean)

Y así es como lo harías con un bucle for:

y <- list()
for (i in seq_along(x)) {
  y[[i]] <- mean(x[[i]])
}
y

No necesita saber lo que hace el código anterior para ver algunos beneficios obvios:

  1. El código purrr es fácil de escribir. Es mucho más sucinto que los bucles for.

  2. El código purrr es fácil de leer . Una vez que conoces el vocabulario, puedes entender inmediatamente lo que hace map(x, mean) .

    Esto no es cierto con los bucles. Incluso si sabe lo que hace for , aún necesita estudiar la configuración y las partes internas del bucle para determinar qué devolverá el bucle.

  3. El código purrr es fácil de pasar a otras funciones, por ejemplo, x %>% map(mean) o mutate(df, avg_x = map(x, mean)) .

  4. El código purrr es fácil de usar. Dado que purrr implementa el ciclo for por usted, no necesita preocuparse de que su ciclo tenga efectos secundarios no deseados, se ejecute más lento de lo que debería o consuma cantidades innecesarias de memoria.

Purrr and Lapply

Las funciones purrr también ofrecen algunas ventajas sobre la familia lapply de R.

  1. Las funciones purrr siempre devuelven el mismo tipo de estructura de datos. Por el contrario, sapply() o mapply() devolverán diferentes tipos de estructuras de datos en diferentes situaciones.

  2. Las funciones purrr comparten la misma sintaxis en todas las funciones, lo que no es cierto para la familia lapply. El primer argumento de lapply() son los datos, pero el primer argumento de mapply() es la función. vapply() , sapply() y mapply() reconocen el argumento USE.NAMES , pero lapply() no. Y, mientras que la mayoría de las funciones lapply usan ... para pasar argumentos a las funciones, mapply() usa el argumento MoreArgs .

  3. Las funciones purrr también te permiten hacer cosas que no puedes hacer con la familia lapply() . Por ejemplo, puede mapear dos vectores con map2() , o las filas de un marco de datos con pmap() . También puede hacer arreglos para devolver la entrada de manera invisible a medida que activa los efectos secundarios con walk() .

Finalmente, purrr contiene atajos que ahorran tiempo para los casos de uso de iteración más comunes.

¿Por qué no Purrr?

Si ya eres un genio con la iteración en R, no hay razón para volver a aprender en qué eres bueno. Es posible que desee pasar su tiempo aprendiendo algo más novedoso.

Sin embargo, si tiene curiosidad o si es nuevo en la iteración en R, este manual le enseñará todo lo que necesita saber para comenzar. Para comenzar, visite el siguiente tutorial, donde aprenderá sobre la familia de funciones de mapas de purrr.

Mapa

La función map() viene en el paquete purrr. purrr es un paquete de herramientas que puede ayudarte a aplicar funciones de forma iterativa.

purrr se instala cuando ejecutas install.packages("tidyverse") .
purrr se carga cuando ejecutas library(tidyverse)

  • Cargue purrr ahora (ya está instalado). Luego haga clic en Enviar respuesta.
install.packages("tidyverse")
## Installing package into '/cloud/lib/x86_64-pc-linux-gnu-library/4.2'
## (as 'lib' is unspecified)
library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.2 ──
## ✔ ggplot2 3.3.6     ✔ purrr   0.3.4
## ✔ tibble  3.1.8     ✔ dplyr   1.0.9
## ✔ tidyr   1.2.0     ✔ stringr 1.4.0
## ✔ readr   2.1.2     ✔ forcats 0.5.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
install.packages("learnr")
## Installing package into '/cloud/lib/x86_64-pc-linux-gnu-library/4.2'
## (as 'lib' is unspecified)

Map()

El trabajo de la función map() de purrr es aplicar una función R a cada elemento de un vector R. map() requiere dos argumentos, en este orden:

  1. Un vector sobre el que iterar. map() funciona tanto con vectores simples como con listas.
  2. Una función para aplicar a cada elemento del vector. Dale a map() el nombre de la función sin comillas y sin paréntesis detrás.

Aquí, map() aplica la función de valor absoluto a cada elemento de negativos .

negatives <- list(-25, -31, -111)
map(negatives, abs)
## [[1]]
## [1] 25
## 
## [[2]]
## [1] 31
## 
## [[3]]
## [1] 111

Piensa en map() así. Cada círculo de cuadrados representa un vector, y cada cuadrado representa un elemento del vector:

  • Use el fragmento de código a continuación para mapear log() sobre los elementos de list1 . Luego haga clic en Enviar respuesta
map(list1, log)

Programación funcional

Puede parecerte raro que map() tome una función como argumento, pero no es raro en absoluto. En R, las funciones son objetos que se pueden pasar como todo lo demás.

Estas preguntas te ayudarán a hacerte una idea.

  • Use este bloque de código como un bloc de notas para ayudarlo a responder las preguntas a continuación.

Por cierto, deberá hacer clic en Ejecutar código arriba al menos una vez antes de poder continuar.

¿Qué pasa con la salida?

Le das a map() un vector y una función. map() siempre te da una lista. El elemento nth de la lista será el resultado de aplicar su función al elemento nth de su vector.

Esto es conveniente por dos razones:

  1. map() puede manejar cualquier cosa que surja de su función, incluso un marco de datos. ¿Por qué? Porque puedes poner cualquier cosa en una lista.
  2. map() es fácil de usar en tuberías porque toma un vector como primer argumento y devuelve un vector (una lista es un tipo de vector). Aquí hay un ejemplo.
  • Prediga qué devolverá este código y luego haga clic en Enviar respuesta.
mtcars %>% 
  map(log) %>% 
  map(round)
## $mpg
##  [1] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 2 3 3 3 4 3 3 3 3 3 3 3 3 3 3 3 3
## 
## $cyl
##  [1] 2 2 1 2 2 2 2 1 1 2 2 2 2 2 2 2 2 1 1 1 1 2 2 2 2 1 1 1 2 2 2 1
## 
## $disp
##  [1] 5 5 5 6 6 5 6 5 5 5 5 6 6 6 6 6 6 4 4 4 5 6 6 6 6 4 5 5 6 5 6 5
## 
## $hp
##  [1] 5 5 5 5 5 5 6 4 5 5 5 5 5 5 5 5 5 4 4 4 5 5 5 6 5 4 5 5 6 5 6 5
## 
## $drat
##  [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1
## 
## $wt
##  [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1
## 
## $qsec
##  [1] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
## 
## $vs
##  [1] -Inf -Inf    0    0 -Inf    0 -Inf    0    0    0    0 -Inf -Inf -Inf -Inf
## [16] -Inf -Inf    0    0    0    0 -Inf -Inf -Inf -Inf    0 -Inf    0 -Inf -Inf
## [31] -Inf    0
## 
## $am
##  [1]    0    0    0 -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf
## [16] -Inf -Inf    0    0    0 -Inf -Inf -Inf -Inf -Inf    0    0    0    0    0
## [31]    0    0
## 
## $gear
##  [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 1
## 
## $carb
##  [1] 1 1 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 1 0 0 1 1 1 1 0 1 1 1 2 2 1

Entradas y Salidas

Argumentos

¿Qué pasa si quieres pasar map() una función que usa argumentos adicionales?

Por ejemplo, le darías a round() un argumento adicional llamado dígitos si quisieras redondear a un cierto número de dígitos más allá del lugar decimal, por ejemplo

round(3.141593, digits = 2)
## [1] 3.14

Puedes pasar argumentos adicionales para tu función to map() como si fueran argumentos of map() . map() enviará los argumentos a su función cuando llame a la función. Casi siempre querrá nombrar estos argumentos, por ejemplo

mtcars %>% 
  map(log) %>% 
  map(round, digits = 2)
## $mpg
##  [1] 3.04 3.04 3.13 3.06 2.93 2.90 2.66 3.19 3.13 2.95 2.88 2.80 2.85 2.72 2.34
## [16] 2.34 2.69 3.48 3.41 3.52 3.07 2.74 2.72 2.59 2.95 3.31 3.26 3.41 2.76 2.98
## [31] 2.71 3.06
## 
## $cyl
##  [1] 1.79 1.79 1.39 1.79 2.08 1.79 2.08 1.39 1.39 1.79 1.79 2.08 2.08 2.08 2.08
## [16] 2.08 2.08 1.39 1.39 1.39 1.39 2.08 2.08 2.08 2.08 1.39 1.39 1.39 2.08 1.79
## [31] 2.08 1.39
## 
## $disp
##  [1] 5.08 5.08 4.68 5.55 5.89 5.42 5.89 4.99 4.95 5.12 5.12 5.62 5.62 5.62 6.16
## [16] 6.13 6.09 4.37 4.33 4.26 4.79 5.76 5.72 5.86 5.99 4.37 4.79 4.55 5.86 4.98
## [31] 5.71 4.80
## 
## $hp
##  [1] 4.70 4.70 4.53 4.70 5.16 4.65 5.50 4.13 4.55 4.81 4.81 5.19 5.19 5.19 5.32
## [16] 5.37 5.44 4.19 3.95 4.17 4.57 5.01 5.01 5.50 5.16 4.19 4.51 4.73 5.58 5.16
## [31] 5.81 4.69
## 
## $drat
##  [1] 1.36 1.36 1.35 1.12 1.15 1.02 1.17 1.31 1.37 1.37 1.37 1.12 1.12 1.12 1.08
## [16] 1.10 1.17 1.41 1.60 1.44 1.31 1.02 1.15 1.32 1.12 1.41 1.49 1.33 1.44 1.29
## [31] 1.26 1.41
## 
## $wt
##  [1] 0.96 1.06 0.84 1.17 1.24 1.24 1.27 1.16 1.15 1.24 1.24 1.40 1.32 1.33 1.66
## [16] 1.69 1.68 0.79 0.48 0.61 0.90 1.26 1.23 1.35 1.35 0.66 0.76 0.41 1.15 1.02
## [31] 1.27 1.02
## 
## $qsec
##  [1] 2.80 2.83 2.92 2.97 2.83 3.01 2.76 3.00 3.13 2.91 2.94 2.86 2.87 2.89 2.89
## [16] 2.88 2.86 2.97 2.92 2.99 3.00 2.83 2.85 2.74 2.84 2.94 2.82 2.83 2.67 2.74
## [31] 2.68 2.92
## 
## $vs
##  [1] -Inf -Inf    0    0 -Inf    0 -Inf    0    0    0    0 -Inf -Inf -Inf -Inf
## [16] -Inf -Inf    0    0    0    0 -Inf -Inf -Inf -Inf    0 -Inf    0 -Inf -Inf
## [31] -Inf    0
## 
## $am
##  [1]    0    0    0 -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf
## [16] -Inf -Inf    0    0    0 -Inf -Inf -Inf -Inf -Inf    0    0    0    0    0
## [31]    0    0
## 
## $gear
##  [1] 1.39 1.39 1.39 1.10 1.10 1.10 1.10 1.39 1.39 1.39 1.39 1.10 1.10 1.10 1.10
## [16] 1.10 1.10 1.39 1.39 1.39 1.10 1.10 1.10 1.10 1.10 1.39 1.61 1.61 1.61 1.61
## [31] 1.61 1.39
## 
## $carb
##  [1] 1.39 1.39 0.00 0.00 0.69 0.00 1.39 0.69 0.69 1.39 1.39 1.10 1.10 1.10 1.39
## [16] 1.39 1.39 0.00 0.69 0.00 0.00 0.69 0.69 1.39 0.69 0.00 0.69 0.69 1.39 1.79
## [31] 2.08 0.69

Formatos de salida

Hasta ahora, todas nuestras funciones han devuelto una lista de números. Esto es un poco tonto, porque (como has visto) puede ser difícil trabajar con listas.

¿Qué sucede si desea devolver los resultados como un vector simple (es decir, no como una lista)?

map_dbl()

Podrías hacer eso con map_dbl() .

map_dbl() funciona exactamente como map() , excepto que devuelve sus resultados en un vector numérico. (dbl es la abreviatura de “doble”, el nombre informático de un número que puede contener un decimal).

  • Cambie el código a continuación para usar map_dbl() y luego haga clic en Enviar respuesta.

[[1]] [1] 0

[[2]] [1] 0.6931472

[[3]] [1] 1.098612

[[4]] [1] 1.386294

[[5]] [1] 1.609438

Otros tipos de salida

Pero supongamos que nuestra función no devuelve dobles. Por ejemplo, str_sub() del paquete stringr devuelve caracteres. Aquí, devolverá el primer carácter de cada cadena.

  • ¿Funcionará el código? Haga clic en Ejecutar código para averiguarlo.

El código no funcionó porque str_sub() devuelve un conjunto de caracteres, pero map_dbl() crea un vector doble (numérico).

En R, cada vector que no es de lista tiene un tipo. Solo puede guardar dobles en un vector doble. Guardarías los caracteres en un vector de caracteres . ¿Estás fuera de suerte?

No. purrr proporciona ocho versiones de map() . Cada uno devuelve sus resultados en un formato diferente.

Función Producción
map() lista
map_chr() vector de caracteres
map_dbl() vector doble (numérico)
map_dfc() marco de datos (columna de salida enlazada)
map_dfr() marco de datos (fila de salida enlazada)
map_int() vector entero
map_lgl() vector lógico
walk() devuelve la entrada de forma invisible (utilizada para desencadenar efectos secundarios)

La última función, walk() , se usa para funciones que no devuelven una salida a la línea de comando, como funciones que trazan gráficos o guardan archivos.

La idea detrás de purrr es que puede elegir la función de mapa que devuelve el tipo de salida que necesita.

strings <- list("Mary", "John", "Jill")

map_chr(strings, str_sub, start = 1, end = 1)
## [1] "M" "J" "J"

Estudio de caso

ldeaths es una lista que registra las muertes mensuales en el Reino Unido por enfermedades pulmonares. Los datos abarcan los años 1974 a 1979 y se dividen por años.

  • Compruébalo. Haga clic en Enviar respuesta para ver el contenido de ldeaths .
ldeaths
##       Jan  Feb  Mar  Apr  May  Jun  Jul  Aug  Sep  Oct  Nov  Dec
## 1974 3035 2552 2704 2554 2014 1655 1721 1524 1596 2074 2199 2512
## 1975 2933 2889 2938 2497 1870 1726 1607 1545 1396 1787 2076 2837
## 1976 2787 3891 3179 2011 1636 1580 1489 1300 1356 1653 2013 2823
## 1977 3102 2294 2385 2444 1748 1554 1498 1361 1346 1564 1640 2293
## 1978 2815 3137 2679 1969 1870 1633 1529 1366 1357 1570 1535 2491
## 1979 3084 2605 2573 2143 1693 1504 1461 1354 1333 1492 1781 1915

Muertes por año

Sería útil saber cuántas personas mueren cada año por enfermedad pulmonar. Entonces podría ver si las muertes disminuyeron con el tiempo. ¿Puedes averiguar?

  • Use una función de mapa para calcular la suma de cada vector en ldeaths . Luego haga clic en Enviar respuesta.
map_dbl( ldeaths , sum )
##  [1] 3035 2552 2704 2554 2014 1655 1721 1524 1596 2074 2199 2512 2933 2889 2938
## [16] 2497 1870 1726 1607 1545 1396 1787 2076 2837 2787 3891 3179 2011 1636 1580
## [31] 1489 1300 1356 1653 2013 2823 3102 2294 2385 2444 1748 1554 1498 1361 1346
## [46] 1564 1640 2293 2815 3137 2679 1969 1870 1633 1529 1366 1357 1570 1535 2491
## [61] 3084 2605 2573 2143 1693 1504 1461 1354 1333 1492 1781 1915

Muertes totales

Dé un paso más.

  • Calcule el número total de muertes en el conjunto de datos. Esta será la suma de su último resultado. Luego haga clic en Enviar respuesta.
sum(map_dbl(ldeaths, sum))
## [1] 148077

TPipes

Ahora que está realizando operaciones de varios pasos, debe comenzar a usar el operador de tubería si aún no lo ha hecho. El operador de tubería ( %>% ) también es excelente para operaciones de un solo paso.

  • Tómese un momento para convertir este código para usar el operador de tubería. Luego haga clic en Enviar respuesta.

    Nota: Recuerde que el operador de tubería toma la salida de lo que sea que esté en su lado izquierdo y la pasa al primer argumento de la función que está en su lado derecho. Así que x %>% f() es lo mismo que f(x) y x %>% f() %>% g() es lo mismo que g(f(x)) .

ldeaths %>% 
  map_dbl(sum) %>%
  sum()
## [1] 148077

Suma por mes

Sumemos los meses para ver si hay un efecto estacional.

Matemáticamente, esto es tan simple como sus cálculos anteriores. Desde el punto de vista programático, es un desafío: sus datos no están configurados de una manera que facilite la suma a lo largo de los meses. Necesitarás una estrategia.

Si ha tomado el manual básico Trabajar con datos recientemente, es posible que tenga una estrategia en mente:

  1. Si puede hacer que sus datos se vean así:
## Warning: The `x` argument of `as_tibble.matrix()` must have unique column names if `.name_repair` is omitted as of tibble 2.0.0.
## Using compatibility `.name_repair`.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.
  1. Luego puede usar la función summarise() de dplyr para sumar las columnas.

Haz exactamente eso, pero con una advertencia justa: te encontrarás con un par de sorpresas, como cuando discutes datos en la vida real.

Step 1 - Un marco de datos

Para el Paso 1, puede usar una función de mapa para combinar sus vectores en un marco de datos. ¿Recuerda qué funciones de mapa devuelven un solo marco de datos? Había dos de ellos.

  1. map_dfr() añade cada elemento al primero como rows (exactamente lo que quieres)
  2. map_dfc() añade cada elemento al primero como columnas

Pero cada función espera iterar sobre un conjunto de marcos de datos y ldeaths contiene un conjunto de vectores. Para hacer que map_dfr() funcione, deberá pasarle una función que convierta los vectores en ldeaths en marcos de datos para que map_dfr() se combine.

as_tibble()

R tiene muchas funciones que pueden convertir un vector en un marco de datos: data.frame() , as.data.frame() , data_frame() , as_data_frame() , son algunas de ellas.

Como resultado, el marco de datos se imprime muy bien en la línea de comandos.

  • Pruébelo. Usa as_tibble() para convertir el siguiente vector en un marco de datos.
named_vec <- c(uno = 1, dos = 2, tres = 3)
as_tibble(named_vec)

Ahora que sabes cómo funciona as_tibble() ,

  • Usa map() para mapear as_tibble() sobre los vectores en ldeaths . Luego haga clic en Enviar respuesta. (Por ahora, use map() en lugar de map_dfr() , esto lo ayudará a ver qué sucede paso a paso a medida que manipula los datos).
  • Inspeccione los resultados de cerca. ¿Lo que sucede?
ldeaths %>% 
  map(as_tibble)
## [[1]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  3035
## 
## [[2]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2552
## 
## [[3]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2704
## 
## [[4]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2554
## 
## [[5]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2014
## 
## [[6]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1655
## 
## [[7]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1721
## 
## [[8]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1524
## 
## [[9]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1596
## 
## [[10]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2074
## 
## [[11]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2199
## 
## [[12]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2512
## 
## [[13]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2933
## 
## [[14]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2889
## 
## [[15]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2938
## 
## [[16]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2497
## 
## [[17]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1870
## 
## [[18]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1726
## 
## [[19]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1607
## 
## [[20]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1545
## 
## [[21]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1396
## 
## [[22]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1787
## 
## [[23]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2076
## 
## [[24]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2837
## 
## [[25]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2787
## 
## [[26]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  3891
## 
## [[27]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  3179
## 
## [[28]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2011
## 
## [[29]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1636
## 
## [[30]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1580
## 
## [[31]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1489
## 
## [[32]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1300
## 
## [[33]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1356
## 
## [[34]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1653
## 
## [[35]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2013
## 
## [[36]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2823
## 
## [[37]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  3102
## 
## [[38]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2294
## 
## [[39]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2385
## 
## [[40]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2444
## 
## [[41]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1748
## 
## [[42]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1554
## 
## [[43]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1498
## 
## [[44]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1361
## 
## [[45]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1346
## 
## [[46]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1564
## 
## [[47]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1640
## 
## [[48]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2293
## 
## [[49]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2815
## 
## [[50]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  3137
## 
## [[51]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2679
## 
## [[52]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1969
## 
## [[53]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1870
## 
## [[54]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1633
## 
## [[55]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1529
## 
## [[56]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1366
## 
## [[57]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1357
## 
## [[58]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1570
## 
## [[59]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1535
## 
## [[60]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2491
## 
## [[61]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  3084
## 
## [[62]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2605
## 
## [[63]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2573
## 
## [[64]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  2143
## 
## [[65]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1693
## 
## [[66]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1504
## 
## [[67]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1461
## 
## [[68]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1354
## 
## [[69]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1333
## 
## [[70]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1492
## 
## [[71]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1781
## 
## [[72]]
## # A tibble: 1 × 1
##   value
##   <dbl>
## 1  1915

Fila o columna?

as_tibble() convirtió cada vector en un marco de datos con una columna . Si desea el marco de datos a continuación, deberá convertir cada vector en un marco de datos con una fila (de esa manera map_dfr() puede apilar las filas una encima de la otra).

ldeaths %>% 
  map(t) %>% 
  map_dfr(as_tibble)

Paso 2 - resumir()

¿Cómo extendería este código con summarise() del paquete dplyr para calcular los totales mensuales?

(Es posible que deba tomar el Manual de trabajo con datos para comprender estas tres secciones finales).

ldeaths %>% 
  map(t) %>% 
  map_dfr(as_tibble)

Esta es una forma segura de hacerlo, pero requiere mucho tipeo; Estoy resumiendo cada columna en el marco de datos. Usemos un atajo en su lugar.

ldeaths %>% 
  map(t) %>% 
  map_dfr(as_tibble) %>% 
  summarise(Jan = sum(Jan), 
            Feb = sum(Feb),
            Mar = sum(Mar),
            Apr = sum(Apr),
            May = sum(May),
            Jun = sum(Jun), 
            Jul = sum(Jul),
            Aug = sum(Aug),
            Sep = sum(Sep),
            Oct = sum(Oct),
            Nov = sum(Nov),
            Dec = sum(Dec))

resumir_todo()

dplyr contiene una variante de summarise() llamada summarise_all() . Para usar summarise_all() , déle un marco de datos y luego una o más funciones para aplicar a cada columna en el marco de datos. summarise_all() aplicará cada función a cada columna y devolverá los resultados como una tabla de resumen.

  • Use summarise_all() y el código a continuación para sumar entre meses. Mira las pistas si te quedas atascado. Luego haga clic en Enviar respuesta.
ldeaths %>% 
  map(t) %>% 
  map_dfr(as_tibble) %>% 
  summarise_all(sum)

El final

Enhorabuena por llegar hasta el final. Has aprendido los entresijos de iterar con map() , pero hay más que saber.

Cuando esté listo, el siguiente tutorial le mostrará cómo ahorrar mucho tiempo con los atajos de sintaxis de map() . También le mostrará qué hacer cuando no pueda encontrar una función para mapear que haga lo que desea.