5/4/2018

Bibliografía

Esta parte se basa en el libro de Hadley Wickham:

dplyr

Funciones para las tareas más comunes:

  • filter
  • select
  • arrange
  • mutate
  • summarise
  • group_by

Muchas formas de hacer lo mismo

library(dplyr)

dplyr es un estándar que simplifica.

Base

  • Esta base contiene datos sobre los datos de sueño de varias mamíferos:
msleep <- read.csv("../data/msleep_ggplot2.csv")
names(msleep)
##  [1] "name"         "genus"        "vore"         "order"       
##  [5] "conservation" "sleep_total"  "sleep_rem"    "sleep_cycle" 
##  [9] "awake"        "brainwt"      "bodywt"

select

Selecciona columnas.

head(select(msleep, name, sleep_total))
##                         name sleep_total
## 1                    Cheetah        12.1
## 2                 Owl monkey        17.0
## 3            Mountain beaver        14.4
## 4 Greater short-tailed shrew        14.9
## 5                        Cow         4.0
## 6           Three-toed sloth        14.4

select (2)

head(select(msleep, -name))
##        genus  vore        order conservation sleep_total sleep_rem
## 1   Acinonyx carni    Carnivora           lc        12.1        NA
## 2      Aotus  omni     Primates         <NA>        17.0       1.8
## 3 Aplodontia herbi     Rodentia           nt        14.4       2.4
## 4    Blarina  omni Soricomorpha           lc        14.9       2.3
## 5        Bos herbi Artiodactyla domesticated         4.0       0.7
## 6   Bradypus herbi       Pilosa         <NA>        14.4       2.2
##   sleep_cycle awake brainwt  bodywt
## 1          NA  11.9      NA  50.000
## 2          NA   7.0 0.01550   0.480
## 3          NA   9.6      NA   1.350
## 4   0.1333333   9.1 0.00029   0.019
## 5   0.6666667  20.0 0.42300 600.000
## 6   0.7666667   9.6      NA   3.850

select (3)

head(select(msleep, starts_with("sl")))
##   sleep_total sleep_rem sleep_cycle
## 1        12.1        NA          NA
## 2        17.0       1.8          NA
## 3        14.4       2.4          NA
## 4        14.9       2.3   0.1333333
## 5         4.0       0.7   0.6666667
## 6        14.4       2.2   0.7666667

Existen muchas variaciones:

  • ends_with
  • contains
  • matches
  • one_ofS

filter

Selecciona filas.

head(filter(msleep, sleep_total >= 16))
##                     name      genus    vore           order conservation
## 1             Owl monkey      Aotus    omni        Primates         <NA>
## 2   Long-nosed armadillo    Dasypus   carni       Cingulata           lc
## 3 North American Opossum  Didelphis    omni Didelphimorphia           lc
## 4          Big brown bat  Eptesicus insecti      Chiroptera           lc
## 5   Thick-tailed opposum Lutreolina   carni Didelphimorphia           lc
## 6       Little brown bat     Myotis insecti      Chiroptera         <NA>
##   sleep_total sleep_rem sleep_cycle awake brainwt bodywt
## 1        17.0       1.8          NA   7.0 0.01550  0.480
## 2        17.4       3.1   0.3833333   6.6 0.01080  3.500
## 3        18.0       4.9   0.3333333   6.0 0.00630  1.700
## 4        19.7       3.9   0.1166667   4.3 0.00030  0.023
## 5        19.4       6.6          NA   4.6      NA  0.370
## 6        19.9       2.0   0.2000000   4.1 0.00025  0.010

filter (2)

Selecciona filas.

head(filter(msleep, sleep_total >= 16, bodywt >= 1))
##                     name      genus    vore           order conservation
## 1   Long-nosed armadillo    Dasypus   carni       Cingulata           lc
## 2 North American Opossum  Didelphis    omni Didelphimorphia           lc
## 3        Giant armadillo Priodontes insecti       Cingulata           en
##   sleep_total sleep_rem sleep_cycle awake brainwt bodywt
## 1        17.4       3.1   0.3833333   6.6  0.0108    3.5
## 2        18.0       4.9   0.3333333   6.0  0.0063    1.7
## 3        18.1       6.1          NA   5.9  0.0810   60.0

filter (3)

head(filter(msleep, order %in% c("Perissodactyla")))
##              name   genus  vore          order conservation sleep_total
## 1           Horse   Equus herbi Perissodactyla domesticated         2.9
## 2          Donkey   Equus herbi Perissodactyla domesticated         3.1
## 3 Brazilian tapir Tapirus herbi Perissodactyla           vu         4.4
##   sleep_rem sleep_cycle awake brainwt  bodywt
## 1       0.6         1.0  21.1   0.655 521.000
## 2       0.4          NA  20.9   0.419 187.000
## 3       1.0         0.9  19.6   0.169 207.501
  • el último usa el operador %in%

arrange

Ordena las filas.

msleep %>% arrange(sleep_total) %>% head
##               name         genus  vore          order conservation
## 1          Giraffe       Giraffa herbi   Artiodactyla           cd
## 2      Pilot whale Globicephalus carni        Cetacea           cd
## 3            Horse         Equus herbi Perissodactyla domesticated
## 4         Roe deer     Capreolus herbi   Artiodactyla           lc
## 5           Donkey         Equus herbi Perissodactyla domesticated
## 6 African elephant     Loxodonta herbi    Proboscidea           vu
##   sleep_total sleep_rem sleep_cycle awake brainwt   bodywt
## 1         1.9       0.4          NA 22.10      NA  899.995
## 2         2.7       0.1          NA 21.35      NA  800.000
## 3         2.9       0.6           1 21.10  0.6550  521.000
## 4         3.0        NA          NA 21.00  0.0982   14.800
## 5         3.1       0.4          NA 20.90  0.4190  187.000
## 6         3.3        NA          NA 20.70  5.7120 6654.000

%>%

Sirve para combinar funciones y poder leerlas de izquierda a derecha.

x %>% f(y) 
#es equivalente a 
f(x,y)

%>% (2)

El nombre de los omnívoros que duermen más de 15 horas:

select(filter(msleep, sleep_total > 15), name)
##                              name
## 1                      Owl monkey
## 2            Long-nosed armadillo
## 3          North American Opossum
## 4                   Big brown bat
## 5            Thick-tailed opposum
## 6                Little brown bat
## 7                           Tiger
## 8                 Giant armadillo
## 9          Arctic ground squirrel
## 10 Golden-mantled ground squirrel
## 11      Eastern american chipmunk
## 12                         Tenrec

Es equivalente a:

msleep %>%
  filter(sleep_total > 15) %>%
  select(name)
##                              name
## 1                      Owl monkey
## 2            Long-nosed armadillo
## 3          North American Opossum
## 4                   Big brown bat
## 5            Thick-tailed opposum
## 6                Little brown bat
## 7                           Tiger
## 8                 Giant armadillo
## 9          Arctic ground squirrel
## 10 Golden-mantled ground squirrel
## 11      Eastern american chipmunk
## 12                         Tenrec

Demo: problema con los ruts

Una tarea concreta: Datos de ZZFF.

rut razon_social empleados
20 213154420012 AAAAA BBBBBBBBB 5
21 215085700011 CCCCCCCC S.A. 2
22 214203290014 DDDDDDD S.A. 1
23 212152060010 EEEEE FFFFFF S.A. 185
24 1215917590016 HHHHHH S.A. 6
25 2215917590016 HHHHHH S.A. 1

Funciones varias

Importantes:

  • mutate, select, filter, arrange
  • ifelse

Auxiliares:

  • nchar
  • as.character
  • substr

Datos para testing

ruts <- c("214203290014", 
          "212152060010",
          "1215917590016", 
          "2215917590016")

Necesitamos una función que nos de el RUT y el local por separado.

Auxiliares

¡Son vectoriales!

ruts
## [1] "214203290014"  "212152060010"  "1215917590016" "2215917590016"
nchar(ruts)
## [1] 12 12 13 13
substr(ruts, 1, 2)
## [1] "21" "21" "12" "22"

ifelse

ruts
## [1] "214203290014"  "212152060010"  "1215917590016" "2215917590016"
ifelse(nchar(ruts)==13, "Trece", "Distinto de Trece")
## [1] "Distinto de Trece" "Distinto de Trece" "Trece"            
## [4] "Trece"

Pregunta

¿Cómo definirían una función que toma un vector de números y devuelve un vector de caracteres "Distinto de trece", "Trece" ?

ruts
## [1] "214203290014"  "212152060010"  "1215917590016" "2215917590016"
trece <- function(vector) {
  ifelse(nchar(ruts)>13, "Trece", "Distinto de Trece")
}
trece(ruts)
## [1] "Distinto de Trece" "Distinto de Trece" "Distinto de Trece"
## [4] "Distinto de Trece"

Solución (1)

Una función que recibe un vector de ruts y me da un vector con el número de local:

extrae_local <- function(ruts) {
  ifelse(nchar(ruts) == 13,
         substr(ruts,1,1),
         1)
}

ruts
## [1] "214203290014"  "212152060010"  "1215917590016" "2215917590016"
extrae_local(ruts)
## [1] "1" "1" "1" "2"

Solución (2)

Una función que recibe un vector de ruts y me da un vector con el número de rut:

extrae_rut <- function(ruts) {
  ifelse(nchar(ruts) == 13,
    substr(ruts,2,13),
    ruts)
}

ruts
## [1] "214203290014"  "212152060010"  "1215917590016" "2215917590016"
extrae_rut(ruts)
## [1] "214203290014" "212152060010" "215917590016" "215917590016"

Solución (3)

Abro los datos:

library(readr)
test <-  read_csv('../data/ruts_ejemplo.csv', col_types= list(rut=col_character(), razon_social=col_character(), empleados=col_double(), ciiu=col_character()))
test
## # A tibble: 6 x 4
##   rut           razon_social      empleados ciiu 
##   <chr>         <chr>                 <dbl> <chr>
## 1 213154420012  AAAAA BBBBBBBBB        5.00 111  
## 2 215085700011  CCCCCCCC S.A.          2.00 112  
## 3 214203290014  DDDDDDD S.A.           1.00 3311 
## 4 212152060010  EEEEE FFFFFF S.A.    185    112  
## 5 1215917590016 HHHHHH S.A.            6.00 3510 
## 6 2215917590016 HHHHHH S.A.            1.00 111

Solución (3)

final <- test %>% mutate(rut_nuevo=extrae_rut(rut), 
                         local=as.numeric(extrae_local(rut)))
final
## # A tibble: 6 x 6
##   rut           razon_social      empleados ciiu  rut_nuevo    local
##   <chr>         <chr>                 <dbl> <chr> <chr>        <dbl>
## 1 213154420012  AAAAA BBBBBBBBB        5.00 111   213154420012  1.00
## 2 215085700011  CCCCCCCC S.A.          2.00 112   215085700011  1.00
## 3 214203290014  DDDDDDD S.A.           1.00 3311  214203290014  1.00
## 4 212152060010  EEEEE FFFFFF S.A.    185    112   212152060010  1.00
## 5 1215917590016 HHHHHH S.A.            6.00 3510  215917590016  1.00
## 6 2215917590016 HHHHHH S.A.            1.00 111   215917590016  2.00

Solución (4)

final <- test %>% 
  mutate(rut_nuevo = extrae_rut(rut), 
         extrae_local = extrae_local(rut)) %>%
  group_by(rut_nuevo) %>%
  summarize(razon_social=first(razon_social),
            empleados = sum(empleados),
            locales = n())

final
## # A tibble: 5 x 4
##   rut_nuevo    razon_social      empleados locales
##   <chr>        <chr>                 <dbl>   <int>
## 1 212152060010 EEEEE FFFFFF S.A.    185          1
## 2 213154420012 AAAAA BBBBBBBBB        5.00       1
## 3 214203290014 DDDDDDD S.A.           1.00       1
## 4 215085700011 CCCCCCCC S.A.          2.00       1
## 5 215917590016 HHHHHH S.A.            7.00       2

Otro problema con datos de ZZFF

Corrección de las exportaciones a Uruguay:

ej <- readRDS('../data/ejemplo_expors.rds')
head(ej$N2) # N1 tiene las exportaciones
## [1] 3382879166    4735149  161700000 1015457002          0  327324647
head(ej$N2_1, 20) # N2_1, N2_2, ... tiene el destino
##  [1] "Brasil"         "Republica Domi" "Brasil"         "Venezuela"     
##  [5] "Seleccionar"    "Paraguay"       "Chile"          "Seleccionar"   
##  [9] "Seleccionar"    "Seleccionar"    "Seleccionar"    "Brasil"        
## [13] "Seleccionar"    "Venezuela"      "Seleccionar"    "Seleccionar"   
## [17] "Seleccionar"    "Mexico"         "Brasil"         "Seleccionar"

head(ej$NP1_2, 20) # NP1_2, NP2_2, ... tiene porcentaje a ese destino
##  [1]  41  50  25  98   0  99  50   0   0   0   0  98   0  84   0   0   0
## [18]  61 100   0

Agrego la tasa de exportaciones a Uruguay:

tasa_expor_uy <- function(N2_1, N2_2, N2_3, N2_4, N2_5, N2_6, N2_7, 
                 N2_8, NP1_2, NP2_2, NP3_2, NP4_2, NP5_2, NP6_2, 
                 NP7_2, NP8_2) {
    case_when(
        N2_1 == "Uruguay" ~ NP1_2,
        N2_2 == "Uruguay" ~ NP2_2,
        N2_3 == "Uruguay" ~ NP3_2,
        N2_4 == "Uruguay" ~ NP4_2,
        N2_5 == "Uruguay" ~ NP5_2,
        N2_6 == "Uruguay" ~ NP6_2,
        N2_7 == "Uruguay" ~ NP7_2,
        N2_8 == "Uruguay" ~ NP8_2,
        TRUE ~ 0L)
}

con_tasa <- ej %>% mutate(tasa_expor_uy = tasa_expor_uy(N2_1, N2_2, 
                   N2_3, N2_4, N2_5, N2_6, N2_7, N2_8, NP1_2, NP2_2, 
                   NP3_2, NP4_2, NP5_2, NP6_2, NP7_2, NP8_2),
                   export_corregidas=N2*(100-tasa_expor_uy)/100)

con_tasa[c(229, 695),c("N2", "export_corregidas", "tasa_expor_uy")]

##           N2 export_corregidas tasa_expor_uy
## 229 76099922          71533927             6
## 695 95398121          62008779            35

Funciones personalizadas

Además de usar las funciones que nos da R, podemos crear las nuestras.

sum.of.squares <- function(x,y) {
  x^2 + y^2
}
sum.of.squares(3, 4)
## [1] 25
sum.of.squares(c(3, 2), c(2, 9))
## [1] 13 85

¡x e y son vectores!

Iteración

Bucles - Permiten repetir una acción:

es_par <- function(num) {
  if (num %% 2 == 0) print("par")
  else print("impar")
}

¿Cuál es la diferencia con ifelse?

Iteración (2)

my_list <- c(2, 3, 4, 5, 6, 7, 8)
n <- length(my_list)
for(i in 1:n) {
  es_par(my_list[[i]])
}
## [1] "par"
## [1] "impar"
## [1] "par"
## [1] "impar"
## [1] "par"
## [1] "impar"
## [1] "par"

Iteración (3)

my_list <- c(2, 3, 4, 5, 6, 7, 8)

sapply(my_list, es_par)
## [1] "par"
## [1] "impar"
## [1] "par"
## [1] "impar"
## [1] "par"
## [1] "impar"
## [1] "par"
## [1] "par"   "impar" "par"   "impar" "par"   "impar" "par"

Ejemplo con CIIUs

Tenemos un archivo con una tabla de correspondencias entre códigos CIIUs y clasificaciones

ciiu clasif
111 Bienes
112 Comercial
113 Bienes
114 Trading

Solución 1

buscar_clasificaciones <- function(vector) {
    buscar_clasificacion <- function(ciiu) {
        read_tsv("../data/ciius.csv", col_types = list(col_character(), col_character())) %>%
            filter(CIIU==ciiu) %>%
            select(Clasificacion) %>%
            as.character
    }
    sapply(vector, buscar_clasificacion)
}

buscar_clasificaciones(c("111", "112", "3311", "3510"))
##                        111                        112 
##                   "Bienes"                   "Bienes" 
##                       3311                       3510 
## "Instalacion y reparacion"         "Bienes Naturales"

test$clasif <- buscar_clasificaciones(test$ciiu)
test
## # A tibble: 6 x 5
##   rut           razon_social      empleados ciiu  clasif                  
##   <chr>         <chr>                 <dbl> <chr> <chr>                   
## 1 213154420012  AAAAA BBBBBBBBB        5.00 111   Bienes                  
## 2 215085700011  CCCCCCCC S.A.          2.00 112   Bienes                  
## 3 214203290014  DDDDDDD S.A.           1.00 3311  Instalacion y reparacion
## 4 212152060010  EEEEE FFFFFF S.A.    185    112   Bienes                  
## 5 1215917590016 HHHHHH S.A.            6.00 3510  Bienes Naturales        
## 6 2215917590016 HHHHHH S.A.            1.00 111   Bienes

Joins

Verbos para dos tablas:

  • left_join, right_join, full_join
  • semi_join, anti_join
  • intersect, union, setdiff

Especificar las columnas

x está en los dos \(data\) \(frames\).

df1 <- data_frame(x = c(1, 2), y = 2:1)
df2 <- data_frame(x = c(1, 3), a = 10, b = "a")
df1
## # A tibble: 2 x 2
##       x     y
##   <dbl> <int>
## 1  1.00     2
## 2  2.00     1

df2
## # A tibble: 2 x 3
##       x     a b    
##   <dbl> <dbl> <chr>
## 1  1.00  10.0 a    
## 2  3.00  10.0 a

La opción by permite elegir los campos cuando tienen distinto nombre o hay varios que coinciden.

left_join

Se queda con todas las filas del primer arg (right_join lo opuesto).

left_join(df1, df2)
## Joining, by = "x"
## # A tibble: 2 x 4
##       x     y     a b    
##   <dbl> <int> <dbl> <chr>
## 1  1.00     2  10.0 a    
## 2  2.00     1  NA   <NA>

Pone NA en los que no aplican y todas las columnas.

inner_join

Se queda con todas las filas que están en df1 que tienen un \(match\) en df2 y todas las columnas de df1 y df2.

inner_join(df1, df2)
## Joining, by = "x"
## # A tibble: 1 x 4
##       x     y     a b    
##   <dbl> <int> <dbl> <chr>
## 1  1.00     2  10.0 a

full_join

Se queda con todas las filas y columnas que están en los dos df.

full_join(df1, df2)
## Joining, by = "x"
## # A tibble: 3 x 4
##       x     y     a b    
##   <dbl> <int> <dbl> <chr>
## 1  1.00     2  10.0 a    
## 2  2.00     1  NA   <NA> 
## 3  3.00    NA  10.0 a

semi_join

Se queda con todas las filas del df1 que tienen un \(match\) en df2 y las columnas de df1.

semi_join(df1, df2)
## Joining, by = "x"
## # A tibble: 1 x 2
##       x     y
##   <dbl> <int>
## 1  1.00     2

anti_join

Saca las filas de df1 que están en df2.

anti_join(df1, df2)
## Joining, by = "x"
## # A tibble: 1 x 2
##       x     y
##   <dbl> <int>
## 1  2.00     1

Otra solución al problema de los CIIUS

tabla <- read_tsv("../data/ciius.csv", 
                  col_types = list(col_character(), col_character()))

test %>% left_join(tabla, c("ciiu"="CIIU"))
test
## # A tibble: 6 x 5
##   rut           razon_social      empleados ciiu  clasif                  
##   <chr>         <chr>                 <dbl> <chr> <chr>                   
## 1 213154420012  AAAAA BBBBBBBBB        5.00 111   Bienes                  
## 2 215085700011  CCCCCCCC S.A.          2.00 112   Bienes                  
## 3 214203290014  DDDDDDD S.A.           1.00 3311  Instalacion y reparacion
## 4 212152060010  EEEEE FFFFFF S.A.    185    112   Bienes                  
## 5 1215917590016 HHHHHH S.A.            6.00 3510  Bienes Naturales        
## 6 2215917590016 HHHHHH S.A.            1.00 111   Bienes

Tidy data

  • Cada observación tiene que ser una fila
  • Cada variable tiene que ser una columna

"Happy families are all alike, every unhappy family is unhappy in its own way." - Leo Tolstoy

"Tidy datasets are all alike, but every messy dataset is messy in its own way." - Hadley Wickham

Tidy data (2)

library(tidyverse)
table1
## # A tibble: 6 x 4
##   country      year  cases population
##   <chr>       <int>  <int>      <int>
## 1 Afghanistan  1999    745   19987071
## 2 Afghanistan  2000   2666   20595360
## 3 Brazil       1999  37737  172006362
## 4 Brazil       2000  80488  174504898
## 5 China        1999 212258 1272915272
## 6 China        2000 213766 1280428583

Calcular la tasa de enfermos

library(tidyverse)
table1 %>% 
  mutate(tasa=cases/population)
## # A tibble: 6 x 5
##   country      year  cases population      tasa
##   <chr>       <int>  <int>      <int>     <dbl>
## 1 Afghanistan  1999    745   19987071 0.0000373
## 2 Afghanistan  2000   2666   20595360 0.000129 
## 3 Brazil       1999  37737  172006362 0.000219 
## 4 Brazil       2000  80488  174504898 0.000461 
## 5 China        1999 212258 1272915272 0.000167 
## 6 China        2000 213766 1280428583 0.000167

Casos por año

library(tidyverse)
table1 %>% 
  group_by(year) %>%
  summarize(n=sum(cases))
## # A tibble: 2 x 2
##    year      n
##   <int>  <int>
## 1  1999 250740
## 2  2000 296920

Untidy data (3)

table2
## # A tibble: 12 x 4
##    country      year type            count
##    <chr>       <int> <chr>           <int>
##  1 Afghanistan  1999 cases             745
##  2 Afghanistan  1999 population   19987071
##  3 Afghanistan  2000 cases            2666
##  4 Afghanistan  2000 population   20595360
##  5 Brazil       1999 cases           37737
##  6 Brazil       1999 population  172006362
##  7 Brazil       2000 cases           80488
##  8 Brazil       2000 population  174504898
##  9 China        1999 cases          212258
## 10 China        1999 population 1272915272
## 11 China        2000 cases          213766
## 12 China        2000 population 1280428583

Untidy data (4)

table3
## # A tibble: 6 x 3
##   country      year rate             
## * <chr>       <int> <chr>            
## 1 Afghanistan  1999 745/19987071     
## 2 Afghanistan  2000 2666/20595360    
## 3 Brazil       1999 37737/172006362  
## 4 Brazil       2000 80488/174504898  
## 5 China        1999 212258/1272915272
## 6 China        2000 213766/1280428583

Untidy data (5)

table4a
## # A tibble: 3 x 3
##   country     `1999` `2000`
## * <chr>        <int>  <int>
## 1 Afghanistan    745   2666
## 2 Brazil       37737  80488
## 3 China       212258 213766

Untidy data (6)

table4b
## # A tibble: 3 x 3
##   country         `1999`     `2000`
## * <chr>            <int>      <int>
## 1 Afghanistan   19987071   20595360
## 2 Brazil       172006362  174504898
## 3 China       1272915272 1280428583

Untidy data

Se pueden lograr los mismos resultados a partir del resto de las tablas. Pero si primero llevamos los datos a una forma "canónica", podemos usarlas funciones de dplyr.

spread

table2
## # A tibble: 12 x 4
##    country      year type            count
##    <chr>       <int> <chr>           <int>
##  1 Afghanistan  1999 cases             745
##  2 Afghanistan  1999 population   19987071
##  3 Afghanistan  2000 cases            2666
##  4 Afghanistan  2000 population   20595360
##  5 Brazil       1999 cases           37737
##  6 Brazil       1999 population  172006362
##  7 Brazil       2000 cases           80488
##  8 Brazil       2000 population  174504898
##  9 China        1999 cases          212258
## 10 China        1999 population 1272915272
## 11 China        2000 cases          213766
## 12 China        2000 population 1280428583
  spread(table2, key=type, value=count )
## # A tibble: 6 x 4
##   country      year  cases population
## * <chr>       <int>  <int>      <int>
## 1 Afghanistan  1999    745   19987071
## 2 Afghanistan  2000   2666   20595360
## 3 Brazil       1999  37737  172006362
## 4 Brazil       2000  80488  174504898
## 5 China        1999 212258 1272915272
## 6 China        2000 213766 1280428583

gather

t4a <- gather(table4a,"1999","2000", key="year", value="cases")
t4b <- gather(table4b,"1999","2000", key="year", value="population")
left_join(t4a, t4b)
## Joining, by = c("country", "year")
## # A tibble: 6 x 4
##   country     year   cases population
##   <chr>       <chr>  <int>      <int>
## 1 Afghanistan 1999     745   19987071
## 2 Brazil      1999   37737  172006362
## 3 China       1999  212258 1272915272
## 4 Afghanistan 2000    2666   20595360
## 5 Brazil      2000   80488  174504898
## 6 China       2000  213766 1280428583

Deberes - swirl

library(swirl)
install_course("Getting and Cleaning Data")