Manipulação de Dados

Introdução

  • Neste contexto, uma das tarefas mais consumidoras de tempo é a preparação dos dados

  • Esta tarefa inclui a recolha dos dados, a sua restruturação para um formato adequado, a exploração de padrões através da visualização preliminar dos dados (o que poderíamos designar por análise de dados exploratória)

  • É importante usar ferramentas que nos permitam ter ganhos de eficiência nestes passos, antes de passarmos à importante fase da modelação

  • O R possui várias bibliotecas adequadas a cada um destes passos (como observámos na importação da dados)

  • Vamos agora discutir uma biblioteca muito útil na restruturação/manipulação de dados

O pacote `dplyr`

O pacote dplyr é utilizado para manipular data frames de forma rápida e conveniente.

library(dplyr)
library(MASS)

my.data <- tbl_df(Boston[,1:10])  # converte o data frame num formato similar
my.data
# A tibble: 506 x 10
      crim    zn indus  chas   nox    rm   age    dis   rad   tax
*    <dbl> <dbl> <dbl> <int> <dbl> <dbl> <dbl>  <dbl> <int> <dbl>
1  0.00632  18.0  2.31     0 0.538 6.575  65.2 4.0900     1   296
2  0.02731   0.0  7.07     0 0.469 6.421  78.9 4.9671     2   242
3  0.02729   0.0  7.07     0 0.469 7.185  61.1 4.9671     2   242
4  0.03237   0.0  2.18     0 0.458 6.998  45.8 6.0622     3   222
5  0.06905   0.0  2.18     0 0.458 7.147  54.2 6.0622     3   222
6  0.02985   0.0  2.18     0 0.458 6.430  58.7 6.0622     3   222
7  0.08829  12.5  7.87     0 0.524 6.012  66.6 5.5605     5   311
8  0.14455  12.5  7.87     0 0.524 6.172  96.1 5.9505     5   311
9  0.21124  12.5  7.87     0 0.524 5.631 100.0 6.0821     5   311
10 0.17004  12.5  7.87     0 0.524 6.004  85.9 6.5921     5   311
# ... with 496 more rows

Verbo: filter

No dplyr verbos são acções de manipulação. Um dos verbos designa-se filter e seleciona linhas segundo o critério dado:

dplyr::filter(my.data, rad==4)
# A tibble: 110 x 10
      crim    zn indus  chas   nox    rm   age    dis   rad   tax
     <dbl> <dbl> <dbl> <int> <dbl> <dbl> <dbl>  <dbl> <int> <dbl>
1  0.62976     0  8.14     0 0.538 5.949  61.8 4.7075     4   307
2  0.63796     0  8.14     0 0.538 6.096  84.5 4.4619     4   307
3  0.62739     0  8.14     0 0.538 5.834  56.5 4.4986     4   307
4  1.05393     0  8.14     0 0.538 5.935  29.3 4.4986     4   307
5  0.78420     0  8.14     0 0.538 5.990  81.7 4.2579     4   307
6  0.80271     0  8.14     0 0.538 5.456  36.6 3.7965     4   307
7  0.72580     0  8.14     0 0.538 5.727  69.5 3.7965     4   307
8  1.25179     0  8.14     0 0.538 5.570  98.1 3.7979     4   307
9  0.85204     0  8.14     0 0.538 5.965  89.2 4.0123     4   307
10 1.23247     0  8.14     0 0.538 6.142  91.7 3.9769     4   307
# ... with 100 more rows

Nota: Usando fluxos de dados

Vamos utilizar o operador %>% que passa o fluxo de dados para a instrução seguinte.

O código anterior passa a ser escrito assim:

my.data %>% dplyr::filter(rad==4)
# A tibble: 110 x 10
      crim    zn indus  chas   nox    rm   age    dis   rad   tax
     <dbl> <dbl> <dbl> <int> <dbl> <dbl> <dbl>  <dbl> <int> <dbl>
1  0.62976     0  8.14     0 0.538 5.949  61.8 4.7075     4   307
2  0.63796     0  8.14     0 0.538 6.096  84.5 4.4619     4   307
3  0.62739     0  8.14     0 0.538 5.834  56.5 4.4986     4   307
4  1.05393     0  8.14     0 0.538 5.935  29.3 4.4986     4   307
5  0.78420     0  8.14     0 0.538 5.990  81.7 4.2579     4   307
6  0.80271     0  8.14     0 0.538 5.456  36.6 3.7965     4   307
7  0.72580     0  8.14     0 0.538 5.727  69.5 3.7965     4   307
8  1.25179     0  8.14     0 0.538 5.570  98.1 3.7979     4   307
9  0.85204     0  8.14     0 0.538 5.965  89.2 4.0123     4   307
10 1.23247     0  8.14     0 0.538 6.142  91.7 3.9769     4   307
# ... with 100 more rows

Nota: Usando fluxos de dados

Alguns exemplos de uso do operador %>%:

1:10 %>% sum()             # igual a sum(1:10)
[1] 55
1:10 %>% cumsum()
 [1]  1  3  6 10 15 21 28 36 45 55
1:10 %>% cumsum() %>% diff()
[1]  2  3  4  5  6  7  8  9 10
1:10 %>% cumsum() %>% diff() %>% sum()
[1] 54
c(2,2,2) %>% `^`(3:5)      # igual a 2^3, 2^4, 2^5
[1]  8 16 32
c(2,2,2) %>% `^`(3:5, .)   # igual a 3^2, 4^2, 5^2
[1]  9 16 25
3:5 %>% `*`(.,.)           # igual a 3*3, 4*4, 5*5
[1]  9 16 25

Verbo: Arrange

Podemos ordenar os dados por colunas:

my.data %>% arrange(rad, desc(tax), age)
# A tibble: 506 x 10
      crim    zn indus  chas    nox    rm   age    dis   rad   tax
     <dbl> <dbl> <dbl> <int>  <dbl> <dbl> <dbl>  <dbl> <int> <dbl>
1  0.02498     0  1.89     0 0.5180 6.540  59.7 6.2669     1   422
2  0.02899    40  1.25     0 0.4290 6.939  34.5 8.7921     1   335
3  0.06211    40  1.25     0 0.4290 6.490  44.4 8.7921     1   335
4  0.03548    80  3.64     0 0.3920 5.876  19.1 9.2203     1   315
5  0.04819    80  3.64     0 0.3920 6.108  32.0 9.2203     1   315
6  0.03466    35  6.06     0 0.4379 6.031  23.3 6.6407     1   304
7  0.05023    35  6.06     0 0.4379 5.706  28.4 6.6407     1   304
8  0.01096    55  2.25     0 0.3890 6.453  31.9 7.3073     1   300
9  0.00632    18  2.31     0 0.5380 6.575  65.2 4.0900     1   296
10 0.00906    90  2.97     0 0.4000 7.088  20.8 7.3073     1   285
# ... with 496 more rows

Verbo: Select

Podemos escolher apenas algumas das colunas disponíveis:

my.data %>% dplyr::select(rad, age)  # o pacote MASS também tem uma funcão select
# A tibble: 506 x 2
     rad   age
*  <int> <dbl>
1      1  65.2
2      2  78.9
3      2  61.1
4      3  45.8
5      3  54.2
6      3  58.7
7      5  66.6
8      5  96.1
9      5 100.0
10     5  85.9
# ... with 496 more rows

Verbo: Select

Podemos escolher um intervalo de colunas:

my.data %>% dplyr::select(nox:dis)  
# A tibble: 506 x 4
     nox    rm   age    dis
*  <dbl> <dbl> <dbl>  <dbl>
1  0.538 6.575  65.2 4.0900
2  0.469 6.421  78.9 4.9671
3  0.469 7.185  61.1 4.9671
4  0.458 6.998  45.8 6.0622
5  0.458 7.147  54.2 6.0622
6  0.458 6.430  58.7 6.0622
7  0.524 6.012  66.6 5.5605
8  0.524 6.172  96.1 5.9505
9  0.524 5.631 100.0 6.0821
10 0.524 6.004  85.9 6.5921
# ... with 496 more rows

Verbo: Select

Ou até usar critérios mais complexos:

my.data %>% dplyr::select(-matches('^[cr]'))  # não começa por c ou r
# A tibble: 506 x 6
      zn indus   nox   age    dis   tax
*  <dbl> <dbl> <dbl> <dbl>  <dbl> <dbl>
1   18.0  2.31 0.538  65.2 4.0900   296
2    0.0  7.07 0.469  78.9 4.9671   242
3    0.0  7.07 0.469  61.1 4.9671   242
4    0.0  2.18 0.458  45.8 6.0622   222
5    0.0  2.18 0.458  54.2 6.0622   222
6    0.0  2.18 0.458  58.7 6.0622   222
7   12.5  7.87 0.524  66.6 5.5605   311
8   12.5  7.87 0.524  96.1 5.9505   311
9   12.5  7.87 0.524 100.0 6.0821   311
10  12.5  7.87 0.524  85.9 6.5921   311
# ... with 496 more rows

Verbo: mutate

Adicionar novas colunas como função de outras:

my.data %>% 
  mutate(twice.age = 2*age, 
         new.col   = sqrt(twice.age),
         good.age  = factor(ifelse(age>50,"good","bad"))) %>%  
  dplyr::select(age:good.age)
# A tibble: 506 x 7
     age    dis   rad   tax twice.age   new.col good.age
   <dbl>  <dbl> <int> <dbl>     <dbl>     <dbl>   <fctr>
1   65.2 4.0900     1   296     130.4 11.419282     good
2   78.9 4.9671     2   242     157.8 12.561847     good
3   61.1 4.9671     2   242     122.2 11.054411     good
4   45.8 6.0622     3   222      91.6  9.570789      bad
5   54.2 6.0622     3   222     108.4 10.411532     good
6   58.7 6.0622     3   222     117.4 10.835128     good
7   66.6 5.5605     5   311     133.2 11.541230     good
8   96.1 5.9505     5   311     192.2 13.863621     good
9  100.0 6.0821     5   311     200.0 14.142136     good
10  85.9 6.5921     5   311     171.8 13.107250     good
# ... with 496 more rows

Verbo: summarise

Podemos fazer resumos dos dados:

my.data %>% summarise(mean.age = mean(age, na.rm = TRUE),
                      sd.age   =   sd(age, na.rm = TRUE))
# A tibble: 1 x 2
  mean.age   sd.age
     <dbl>    <dbl>
1  68.5749 28.14886

Verbo: slice

Este verbo permite selecionar linhas:

my.data %>% slice(c(2:6,10,n()))  # n() representa a última linha
# A tibble: 7 x 10
     crim    zn indus  chas   nox    rm   age    dis   rad   tax
    <dbl> <dbl> <dbl> <int> <dbl> <dbl> <dbl>  <dbl> <int> <dbl>
1 0.02731   0.0  7.07     0 0.469 6.421  78.9 4.9671     2   242
2 0.02729   0.0  7.07     0 0.469 7.185  61.1 4.9671     2   242
3 0.03237   0.0  2.18     0 0.458 6.998  45.8 6.0622     3   222
4 0.06905   0.0  2.18     0 0.458 7.147  54.2 6.0622     3   222
5 0.02985   0.0  2.18     0 0.458 6.430  58.7 6.0622     3   222
6 0.17004  12.5  7.87     0 0.524 6.004  85.9 6.5921     5   311
7 0.04741   0.0 11.93     0 0.573 6.030  80.8 2.5050     1   273

Extrair linhas únicas

Podemos ir buscar os valores únicos de uma dada coluna:

my.data %>% 
  dplyr::select(tax) %>%    # selecionar as taxas
  distinct(tax) %>%         # escolher as distintas
  arrange(tax) %>%          # ordená-las
  as.list()                 # transformar em lista
$tax
 [1] 187 188 193 198 216 222 223 224 226 233 241 242 243 244 245 247 252
[18] 254 255 256 264 265 270 273 276 277 279 280 281 284 285 287 289 293
[35] 296 300 304 305 307 311 313 315 329 330 334 335 337 345 348 351 352
[52] 358 370 384 391 398 402 403 411 422 430 432 437 469 666 711

Amostragem

O pacote permite realizar amostragem de forma sucinta:

sample_n(my.data, 6)                     # amostra com 6 linhas
sample_frac(my.data, .03)                # amostra com 3% dos dados
sample_frac(my.data, .03, replace=TRUE ) # amostra com bootstrap

sample_n(my.data[1:5,], size=10, weight=5:1, replace=TRUE) # amostragem ponderada

Operações em Grupos

É possível dividir a tabela em grupos – dado um critério – de modo a repetir uma operação sobre os vários grupos:

my.data %>%
  group_by(tax) %>%                  # agrupar por taxas iguais
  summarise(count=n(), mean.age=mean(age, na.rm=TRUE)) 
# A tibble: 66 x 3
     tax count mean.age
   <dbl> <int>    <dbl>
1    187     1 36.10000
2    188     7 89.07143
3    193     8 75.48750
4    198     1 24.80000
5    216     5 48.62000
6    222     7 57.15714
7    223     5 46.08000
8    224    10 42.33000
9    226     1 21.90000
10   233     9 40.65556
# ... with 56 more rows

Operações em Grupos

Existem várias operações disponíveis:

my.data %>%
  group_by(rad) %>%
  summarise(n.taxes    = n(), 
            diff.taxes = n_distinct(tax), 
            min.tax    = min(tax), 
            median.tax = median(tax),
            max.tax    = max(tax))
# A tibble: 9 x 6
    rad n.taxes diff.taxes min.tax median.tax max.tax
  <int>   <int>      <int>   <dbl>      <dbl>   <dbl>
1     1      20         12     198      284.5     422
2     2      24          7     188      270.0     348
3     3      38         11     193      233.0     469
4     4     110         21     224      306.0     711
5     5     115         16     187      358.0     403
6     6      26          4     293      391.0     432
7     7      17          3     222      330.0     330
8     8      24          2     284      307.0     307
9    24     132          1     666      666.0     666

Operações em Grupos

É mesmo possível usar as nossas próprias funções:

my.mode <- function(x) {
  ux <- unique(x)
  ux[which.max(tabulate(match(x, ux)))]
}

my.data %>%
  group_by(rad) %>%
  summarise(mode = my.mode(tax))
# A tibble: 9 x 2
    rad  mode
  <int> <dbl>
1     1   273
2     2   188
3     3   233
4     4   307
5     5   403
6     6   432
7     7   330
8     8   307
9    24   666

Operações em Grupos

Os grupos podem ter subgrupos:

my.data %>%
  group_by(tax, rad) %>%  # cada grupo taxa tem subgrupos rad
  summarise(size=n()) %>%
  arrange(tax)
Source: local data frame [77 x 3]
Groups: tax [66]

     tax   rad  size
   <dbl> <int> <int>
1    187     5     1
2    188     2     7
3    193     3     8
4    198     1     1
5    216     3     1
6    216     5     4
7    222     3     3
8    222     7     4
9    223     3     5
10   224     4     2
# ... with 67 more rows

Operações em Grupos

Por cada summarise desaparece um nível de subgrupo:


my.data %>%
  group_by(tax, rad) %>%
  summarise(size=n())
Source: local data frame [77 x 3]
Groups: tax [?]

     tax   rad  size
   <dbl> <int> <int>
1    187     5     1
2    188     2     7
3    193     3     8
4    198     1     1
5    216     3     1
6    216     5     4
7    222     3     3
8    222     7     4
9    223     3     5
10   224     4     2
# ... with 67 more rows


my.data %>%
  group_by(tax, rad) %>%  
  summarise(size=n()) %>%
  summarise(sum=sum(size))
# A tibble: 66 x 2
     tax   sum
   <dbl> <int>
1    187     1
2    188     7
3    193     8
4    198     1
5    216     5
6    222     7
7    223     5
8    224    10
9    226     1
10   233     9
# ... with 56 more rows

Exercícios

Carregar a seguinte tabela do Bureau of Transportation Statistics:

library(nycflights13)    # install.packages("nycflights13")
flights
# A tibble: 336,776 x 19
    year month   day dep_time sched_dep_time dep_delay arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>
1   2013     1     1      517            515         2      830
2   2013     1     1      533            529         4      850
3   2013     1     1      542            540         2      923
4   2013     1     1      544            545        -1     1004
5   2013     1     1      554            600        -6      812
6   2013     1     1      554            558        -4      740
7   2013     1     1      555            600        -5      913
8   2013     1     1      557            600        -3      709
9   2013     1     1      557            600        -3      838
10  2013     1     1      558            600        -2      753
# ... with 336,766 more rows, and 12 more variables: sched_arr_time <int>,
#   arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>,
#   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#   minute <dbl>, time_hour <time>

Exercícios: filter

Ver os voos do dia 1 de Janeiro:

# A tibble: 842 x 19
    year month   day dep_time sched_dep_time dep_delay arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>
1   2013     1     1      517            515         2      830
2   2013     1     1      533            529         4      850
3   2013     1     1      542            540         2      923
4   2013     1     1      544            545        -1     1004
5   2013     1     1      554            600        -6      812
6   2013     1     1      554            558        -4      740
7   2013     1     1      555            600        -5      913
8   2013     1     1      557            600        -3      709
9   2013     1     1      557            600        -3      838
10  2013     1     1      558            600        -2      753
# ... with 832 more rows, and 12 more variables: sched_arr_time <int>,
#   arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>,
#   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#   minute <dbl>, time_hour <time>

Exercícios: filter

Ver os voos de Novembro e Dezembro (operador pertença é dado por %in%):

# A tibble: 55,403 x 19
    year month   day dep_time sched_dep_time dep_delay arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>
1   2013    11     1        5           2359         6      352
2   2013    11     1       35           2250       105      123
3   2013    11     1      455            500        -5      641
4   2013    11     1      539            545        -6      856
5   2013    11     1      542            545        -3      831
6   2013    11     1      549            600       -11      912
7   2013    11     1      550            600       -10      705
8   2013    11     1      554            600        -6      659
9   2013    11     1      554            600        -6      826
10  2013    11     1      554            600        -6      749
# ... with 55,393 more rows, and 12 more variables: sched_arr_time <int>,
#   arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>,
#   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#   minute <dbl>, time_hour <time>

Exercícios: filter

Ver os voos que não partiram ou chegaram atrasados mais que 15 minutos (operadores lógicos dados por !, & e |):

# A tibble: 235,822 x 19
    year month   day dep_time sched_dep_time dep_delay arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>
1   2013     1     1      517            515         2      830
2   2013     1     1      544            545        -1     1004
3   2013     1     1      554            600        -6      812
4   2013     1     1      554            558        -4      740
5   2013     1     1      557            600        -3      709
6   2013     1     1      557            600        -3      838
7   2013     1     1      558            600        -2      753
8   2013     1     1      558            600        -2      849
9   2013     1     1      558            600        -2      853
10  2013     1     1      558            600        -2      924
# ... with 235,812 more rows, and 12 more variables: sched_arr_time <int>,
#   arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>,
#   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#   minute <dbl>, time_hour <time>

Exercícios: filter

Que voos não possuem a ordem de partida? Usar a função is.na().

# A tibble: 8,255 x 19
    year month   day dep_time sched_dep_time dep_delay arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>
1   2013     1     1       NA           1630        NA       NA
2   2013     1     1       NA           1935        NA       NA
3   2013     1     1       NA           1500        NA       NA
4   2013     1     1       NA            600        NA       NA
5   2013     1     2       NA           1540        NA       NA
6   2013     1     2       NA           1620        NA       NA
7   2013     1     2       NA           1355        NA       NA
8   2013     1     2       NA           1420        NA       NA
9   2013     1     2       NA           1321        NA       NA
10  2013     1     2       NA           1545        NA       NA
# ... with 8,245 more rows, and 12 more variables: sched_arr_time <int>,
#   arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>,
#   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#   minute <dbl>, time_hour <time>

Exercícios: arrange

Ordenar decrescentemente por atraso à chegada:

# A tibble: 336,776 x 19
    year month   day dep_time sched_dep_time dep_delay arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>
1   2013     1     9      641            900      1301     1242
2   2013     6    15     1432           1935      1137     1607
3   2013     1    10     1121           1635      1126     1239
4   2013     9    20     1139           1845      1014     1457
5   2013     7    22      845           1600      1005     1044
6   2013     4    10     1100           1900       960     1342
7   2013     3    17     2321            810       911      135
8   2013     6    27      959           1900       899     1236
9   2013     7    22     2257            759       898      121
10  2013    12     5      756           1700       896     1058
# ... with 336,766 more rows, and 12 more variables: sched_arr_time <int>,
#   arr_delay <dbl>, carrier <chr>, flight <int>, tailnum <chr>,
#   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#   minute <dbl>, time_hour <time>

Exercícios: select

Selecionar apenas as datas dos voos:

# A tibble: 336,776 x 3
    year month   day
   <int> <int> <int>
1   2013     1     1
2   2013     1     1
3   2013     1     1
4   2013     1     1
5   2013     1     1
6   2013     1     1
7   2013     1     1
8   2013     1     1
9   2013     1     1
10  2013     1     1
# ... with 336,766 more rows

Exercícios: mutate

Ordenar os voos por maior recuperação de tempo por distancia:

# A tibble: 336,776 x 7
   flight dep_delay arr_delay distance air_time  gain  gain_rate
    <int>     <dbl>     <dbl>    <dbl>    <dbl> <dbl>      <dbl>
1    3322        26       -21       94       26   -47 -108.46154
2    3544        21       -21       94       24   -42 -105.00000
3    4191        -3       -44       94       24   -41 -102.50000
4    4218       122        78       94       27   -44  -97.77778
5    3793        58        16       94       26   -42  -96.92308
6    3864        47         9       94       24   -38  -95.00000
7    4218        -2       -37       94       23   -35  -91.30435
8    4191        84        46       94       25   -38  -91.20000
9    3793        -6       -47       94       27   -41  -91.11111
10   3793        19       -20       94       26   -39  -90.00000
# ... with 336,766 more rows

Exercícios: group_by e summarise

Calcular a recuperação do atraso inicial por companhia aérea:



# A tibble: 16 x 2
   carrier mean.gain
     <chr>     <dbl>
1       9E     -9.06
2       AA     -8.20
3       AS    -15.76
4       B6     -3.51
5       DL     -7.58
6       EV     -4.04
7       F9      1.72
8       FL      1.51
9       HA    -11.82
10      MQ      0.33
11      OO     -0.66
12      UA     -8.46
13      US     -1.62
14      VX    -10.99
15      WN     -8.01
16      YV     -3.34


plot of chunk unnamed-chunk-29

Exercícios: group_by e summarise

Contar quantos voos houve por cada dia do ano:

# A tibble: 365 x 2
     dep.date count
        <chr> <int>
1  2013-01-01   842
2  2013-01-02   943
3  2013-01-03   914
4  2013-01-04   915
5  2013-01-05   720
6  2013-01-06   832
7  2013-01-07   933
8  2013-01-08   899
9  2013-01-09   902
10 2013-01-10   932
# ... with 355 more rows

Exercícios: group_by e summarise

Calcular o atraso médio por cada voo:


# A tibble: 4,037 x 3
   tailnum  delay count
     <chr>  <dbl> <int>
1   D942DN 31.500     4
2   N0EGMQ  9.983   352
3   N10156 12.717   145
4   N102UW  2.938    48
5   N103US -6.935    46
6   N104UW  1.804    46
7   N10575 20.691   269
8   N105UW -0.267    45
9   N107US -5.732    41
10  N108UW -1.250    60
# ... with 4,027 more rows


plot of chunk unnamed-chunk-32

continuação...

O histograma anterior mostra a existência de atrasos médios muito grandes (há voos com mais de 300 minutos de atraso!). Mas se usarmos outra visualização verificamos que isso ocorre quando o número de amostras por voo é pequeno:

plot of chunk unnamed-chunk-33

Exemplo: Manipular e visualizar

Queremos estudar o atraso médio para cada destino em relação à sua distância:

flights %>% 
  group_by(dest) %>% 
  summarise(
    count = n(),
    dist = mean(distance, na.rm = TRUE),
    delay = mean(arr_delay, na.rm = TRUE)) %>% 
  filter(count > 20)            # apenas voos com suficiente amostras
# A tibble: 96 x 4
    dest count      dist     delay
   <chr> <int>     <dbl>     <dbl>
1    ABQ   254 1826.0000  4.381890
2    ACK   265  199.0000  4.852273
3    ALB   439  143.0000 14.397129
4    ATL 17215  757.1082 11.300113
5    AUS  2439 1514.2530  6.019909
6    AVL   275  583.5818  8.003831
7    BDL   443  116.0000  7.048544
8    BGR   375  378.0000  8.027933
9    BHM   297  865.9966 16.877323
10   BNA  6333  758.2135 11.812459
# ... with 86 more rows

Exemplo: Manipular e visualizar

plot of chunk unnamed-chunk-36

Fundir data frames

O pacote dplyr pode fundir tabelas usando as suas instruções join:


df1 <- data.frame(id=1:3, m1=c(.1,.2,.3))
df2 <- data.frame(id=2:4, m2=letters[1:3])
df1
  id  m1
1  1 0.1
2  2 0.2
3  3 0.3
df2
  id m2
1  2  a
2  3  b
3  4  c
left_join(df1,df2,by="id")
  id  m1   m2
1  1 0.1 <NA>
2  2 0.2    a
3  3 0.3    b


right_join(df1,df2,by="id")
  id  m1 m2
1  2 0.2  a
2  3 0.3  b
3  4  NA  c
inner_join(df1,df2,by="id")
  id  m1 m2
1  2 0.2  a
2  3 0.3  b
full_join(df1,df2,by="id")
  id  m1   m2
1  1 0.1 <NA>
2  2 0.2    a
3  3 0.3    b
4  4  NA    c