Switch to English | Cambiar a español

1 Sintaxe do R

O R é como uma calculadora, podemos fazer operações matemáticas, por exemplo:

2 + 2
## [1] 4

O R é uma linguagem de programação orientada a objetos, o que significa que criamos objetos que contêm informações. No R, você pode obter os mesmos resultados usando abordagens diferentes. Por exemplo, para criar um objeto, basta digitar um nome para o objeto e atribuir um valor a ele usando os operadores = ou <-. Podemos fazer operações com objetos do mesmo tipo, por exemplo:

x = 2 # cria um novo objeto com o operador =
y <- 2 # cria um novo objeto com o operador <-
x + y # faz uma operação com os objetos
## [1] 4

1.1 Vetores no R

Você pode armazenar mais de um valor usando vetores. Para criar um vetor de números, usamos c(). Por exemplo, vamos armazenar uma sequência de números de 5 a 10 usando duas abordagens diferentes e depois perguntar ao R se os objetos são iguais. Dica: usar as teclas “alt” + “-” adicionará automaticamente o operador <-. A escolha do operador de atribuição é uma questão de preferência. Pessoalmente, acho mais fácil ler o código com o operador <-, mas muitas pessoas usam =.

x <- c(5, 6, 7, 8, 9, 10) # criar uma sequência de 5 a 10
y = 5:10 # criar a mesma sequência, mas com uma abordagem diferente
x == y # perguntar ao R se os objetos têm as mesmas informações
## [1] TRUE TRUE TRUE TRUE TRUE TRUE

Observe que no exemplo anterior comparamos dois objetos usando ==. Dessa forma, informamos ao R que queremos COMPARAR e não atribuir (lembre-se de que para atribuir você usa apenas um símbolo =).

Quando temos um vetor, podemos solicitar ao R valores específicos dentro de um objeto usando o operador [ ] e especificando quais valores queremos.

# Aqui pedimos o terceiro valor da nossa sequência
x[3]
## [1] 7
# Agora multiplicamos o terceiro valor da sequência x pelo quinto valor da sequência y
x[3] * y[5]
## [1] 63

1.2 Funções

O R possui muitas funções básicas, mas também podemos definir novas funções. Ao usar o R Studio, a tecla Tab nos ajuda a auto completar, o que pode ser muito útil quando não lembramos o nome exato das funções disponíveis. A melhor parte da programação em R é que ele possui uma comunidade muito ativa. Como é de código aberto, qualquer pessoa pode criar funções e compilá-las em um pacote (ou library, biblioteca). Podemos baixar esses pacotes e acessar novas funções. Funções em R requerem argumentos, que podem ser vistos na documentação da função ou pressionando a tecla Tab quando estamos dentro da função.

# Para obter a soma de um vetor de números em um objeto, usamos a função sum()
sum(x)
## [1] 45

Podemos colocar funções dentro de funções, por exemplo, para obter \(\sqrt{\sum_1^n x}\) a raiz quadrada da soma dos números em x, podemos usar:

sqrt(sum(x))
## [1] 6.708204

Criar funções em R não é tão complicado quanto parece e pode ser muito útil quando precisamos realizar trabalhos repetitivos. Para definir uma função, precisamos incluir os argumentos desejados e o que faremos com esses argumentos. Por exemplo, a seguinte função tem apenas um argumento que é um nome (string) e apenas concatena um texto antes e depois:

F1 <- function(name){
  paste("Olá", name, "! bem-vindo ao mundo do R (: !") # concatena o nome com um texto
}

# Testando a função (Coloque seu nome)
F1(name = "Pablo")
## [1] "Olá Pablo ! bem-vindo ao mundo do R (: !"

Além de armazenar números nos objetos em R, também podemos armazenar texto, matrizes, tabelas, objetos espaciais, imagens e outros tipos de objetos. A seguir, iremos importar nossos próprios dados e realizar algumas manipulações no R.

Exercício: Crie uma função que execute a operação \(\sqrt{\sum_1^n x}\) que você fez anteriormente com o código sqrt(sum(x)).

1.3 Tipos de variáveis

Existem diferentes tipos de variáveis no R. Até agora usamos os tipos numérico e string. Se você quiser saber qual é o tipo de variável de um determinado objeto, você pode usar a função class(). Vamos experimentar.

class(x)
## [1] "numeric"

Exercício: Qual é o tipo de variável do resultado da primeira função que você definiu F1()?

Os tipos de variáveis mais comumente usados incluem:

  • numeric São variáveis numéricas contínuas COM valores decimais. Por exemplo: Kg de produto importado, probabilidade de um evento ocorrer.
  • integer Essas variáveis são números inteiros SEM valores decimais. Por exemplo: Número de animais, número de remessas, etc.
  • character Variáveis alfanuméricas. Por exemplo: nome de uma região, nome de uma doença, ID da fazenda.
  • factor Variável alfanumérica com categorias ou níveis específicos. Por exemplo: tipo de produto importado, tipo de fazenda, etc.

1.4 Introdução aos pipes

A biblioteca dplyr possui várias funções que podem ajudar a limpar, criar novas variáveis e modificar nossos dados de outras maneiras.

# se não tivermos a biblioteca instalada, precisaremos instalá-la usando:
# install.packages("dplyr")
# carregamos a biblioteca:
library(dplyr)

O dplyr introduz um novo operador chamado pipes (%>%), que pode conectar várias funções a um objeto. Isso é uma alternativa para escrever várias funções em uma única “linha de código” de maneira mais organizada. Por exemplo, se quisermos executar a função F1() seguida por outra função F2() para o objeto x:

F2(F1(x)) é equivalente a x %>% F1() %>% F2()

Como você pode perceber, para ler o código F2(F1(x)), temos que ir de dentro para fora para ver a ordem de execução das funções, mas quando lemos x %>% F1() %>% F2(), lemos da esquerda para a direita, da mesma forma como normalmente leríamos qualquer texto em uma língua ocidental.

Sugestão: podemos usar as teclas Ctrl + shift + m para inserir o operador %>%.

# Nós usamos anteriormente este código para calcular a raiz quadrada da soma de x
sqrt(sum(x))
## [1] 6.708204

Usando os pipes, podemos fazer o mesmo de forma mais organizada, escrevendo a ordem de execução da esquerda para a direita.

x %>% # Primeiro chamamos os dados
  sum() %>% # Somamos todos os valores
  sqrt() # Calculamos a raiz quadrada
## [1] 6.708204

Você perceberá que as saídas são exatamente as mesmas. Sinta-se à vontade para usar a sintaxe que preferir, mas para este curso, usaremos principalmente os pipes e escreveremos o código da esquerda para a direita.

2 Manipulação de dados

O R pode importar dados em diferentes formatos. Os mais comuns são arquivos do Excel (.csv, .xls e .xlsx), arquivos de texto (.txt) e dados espaciais (.shp), sobre os quais falaremos com mais detalhes posteriormente. Para ler arquivos .xls, .xlsx e .shp, precisaremos instalar algumas bibliotecas. Para instalar uma nova biblioteca, você precisa estar conectado à internet e usar a função install.packages() para instalar a biblioteca. Depois de instalada, você pode carregar a biblioteca usando a função library().

Faça o download do arquivo do Excel a partir deste link. Não é necessário ter uma conta no Box.

Sugestão: Às vezes, quando queremos usar apenas uma função de uma biblioteca, podemos simplesmente escrever o nome da biblioteca seguido do operador :: e o nome da função, por exemplo: pacote::funcao(). Dessa forma, não precisamos carregar a biblioteca inteira.

# Se a biblioteca não estiver instalada, use:
# install.packages("readxl")

# Importe o arquivo do Excel
PRRS <- readxl::read_xlsx("Data/PRRS.xlsx")

O formato mais popular para tabelas em R é chamado de data.frame, quando importamos os dados de um arquivo .csv ou .xlsx. Podemos verificar qual tipo de objeto é usando a função class():

# Verificar a classe de um determinado objeto
class(PRRS)
## [1] "tbl_df"     "tbl"        "data.frame"

É possível que objetos possam ter mais de uma classe. No exemplo anterior, você pode perceber que o objeto PRRS possui 3 tipos diferentes de classe.

Na seguinte seção, abordaremos alguns conceitos básicos de manipulação de dados, isso inclui criar, modificar e resumir variáveis em nossos dados.

2.1 Reduzindo nossos dados

Às vezes, queremos selecionar colunas e linhas específicas em nossos dados para reduzir a dimensionalidade. Para isso, podemos usar as funções:

  • select() para selecionar colunas específicas
  • slice() para selecionar linhas específicas com base na posição
  • filter() para selecionar linhas específicas com base em uma condição

2.1.1 Selecionando colunas específicas

PRRS %>%  # o nome de nossos dados
  select(Result, farm_type) # queremos selecionar apenas as colunas Result e farm_type
## # A tibble: 1,353 × 2
##    Result farm_type
##    <chr>  <chr>    
##  1 No     sow farm 
##  2 No     sow farm 
##  3 No     sow farm 
##  4 Yes    sow farm 
##  5 Yes    sow farm 
##  6 Yes    sow farm 
##  7 Yes    sow farm 
##  8 Yes    sow farm 
##  9 Yes    sow farm 
## 10 Yes    sow farm 
## # ℹ 1,343 more rows

Também podemos especificar quais colunas NÃO queremos mostrar em nossos dados:

PRRS %>% 
  select(-Age, -id) # com '-' antes do nome, excluiremos a coluna dos dados
## # A tibble: 1,353 × 6
##    Result Sex   OtherSpecies name                    farm_type County       
##    <chr>  <chr>        <dbl> <chr>                   <chr>     <chr>        
##  1 No     H                0 Armstrong Research Farm sow farm  Pottawattamie
##  2 No     H                0 Armstrong Research Farm sow farm  Pottawattamie
##  3 No     H                0 Armstrong Research Farm sow farm  Pottawattamie
##  4 Yes    H                0 Armstrong Research Farm sow farm  Pottawattamie
##  5 Yes    H                0 Armstrong Research Farm sow farm  Pottawattamie
##  6 Yes    H                0 Armstrong Research Farm sow farm  Pottawattamie
##  7 Yes    M                0 Armstrong Research Farm sow farm  Pottawattamie
##  8 Yes    M                0 Armstrong Research Farm sow farm  Pottawattamie
##  9 Yes    M                0 Armstrong Research Farm sow farm  Pottawattamie
## 10 Yes    H                0 Armstrong Research Farm sow farm  Pottawattamie
## # ℹ 1,343 more rows

2.1.2 Filtrando linhas específicas

Essa seleção funciona com base na lógica booleana, então podemos especificar uma condição e o R mostrará apenas as linhas que satisfazem essa condição. Por exemplo, vamos filtrar apenas as observações de granjas de suínos:

PRRS %>% 
  filter(farm_type == 'boar stud') # usaremos o operador de igualdade para isso
## # A tibble: 19 × 8
##    Result Sex     Age OtherSpecies    id name                   farm_type County
##    <chr>  <chr> <dbl>        <dbl> <dbl> <chr>                  <chr>     <chr> 
##  1 No     H        48            0    32 Farm Sweet Farm at Ro… boar stud Shelby
##  2 No     H        60            0    32 Farm Sweet Farm at Ro… boar stud Shelby
##  3 Yes    H        60            0    32 Farm Sweet Farm at Ro… boar stud Shelby
##  4 Yes    H        15            0    32 Farm Sweet Farm at Ro… boar stud Shelby
##  5 No     H        68            0    32 Farm Sweet Farm at Ro… boar stud Shelby
##  6 No     M         6            0    32 Farm Sweet Farm at Ro… boar stud Shelby
##  7 No     H        75            0    32 Farm Sweet Farm at Ro… boar stud Shelby
##  8 No     H         6            0    32 Farm Sweet Farm at Ro… boar stud Shelby
##  9 No     H       110            0    32 Farm Sweet Farm at Ro… boar stud Shelby
## 10 No     H        36            0    32 Farm Sweet Farm at Ro… boar stud Shelby
## 11 No     M        12            0    32 Farm Sweet Farm at Ro… boar stud Shelby
## 12 No     H        62            0    32 Farm Sweet Farm at Ro… boar stud Shelby
## 13 No     H        48            0    32 Farm Sweet Farm at Ro… boar stud Shelby
## 14 No     H        62            0    32 Farm Sweet Farm at Ro… boar stud Shelby
## 15 No     H        95            0    32 Farm Sweet Farm at Ro… boar stud Shelby
## 16 Yes    M        24            0    32 Farm Sweet Farm at Ro… boar stud Shelby
## 17 Yes    H        38            0    32 Farm Sweet Farm at Ro… boar stud Shelby
## 18 No     H        38            0    32 Farm Sweet Farm at Ro… boar stud Shelby
## 19 No     M        24            0    32 Farm Sweet Farm at Ro… boar stud Shelby

2.2 Criando ou modificando variáveis

Para criar uma nova variável, podemos usar a função mutate(). Por exemplo, vamos criar uma nova variável que nos informará se o tipo de granja é uma granja de matrizes ou não. Para isso, usaremos a variável farm_type, que já contém informações sobre diferentes tipos de granjas.

# Criando uma nova variável
PRRS %>% # nome do conjunto de dados
  mutate( # mutate é a função que usamos para criar novas variáveis
    SowFarm = ifelse(farm_type == 'sow farm', 1, 0) # criaremos uma variável binária em que 1 = granja de matrizes, 0 = qualquer outro tipo de granja
  ) 
## # A tibble: 1,353 × 9
##    Result Sex     Age OtherSpecies    id name           farm_type County SowFarm
##    <chr>  <chr> <dbl>        <dbl> <dbl> <chr>          <chr>     <chr>    <dbl>
##  1 No     H        18            0    23 Armstrong Res… sow farm  Potta…       1
##  2 No     H        60            0    23 Armstrong Res… sow farm  Potta…       1
##  3 No     H        60            0    23 Armstrong Res… sow farm  Potta…       1
##  4 Yes    H        36            0    23 Armstrong Res… sow farm  Potta…       1
##  5 Yes    H        50            0    23 Armstrong Res… sow farm  Potta…       1
##  6 Yes    H        16            0    23 Armstrong Res… sow farm  Potta…       1
##  7 Yes    M        15            0    23 Armstrong Res… sow farm  Potta…       1
##  8 Yes    M        22            0    23 Armstrong Res… sow farm  Potta…       1
##  9 Yes    M        30            0    23 Armstrong Res… sow farm  Potta…       1
## 10 Yes    H        14            0    23 Armstrong Res… sow farm  Potta…       1
## # ℹ 1,343 more rows

Observe que no trecho de código anterior, não atribuímos o resultado a um objeto, o que significa que o R apenas irá mostrá-lo e não salvá-lo. Para salvá-lo, lembre-se de que usamos o operador de atribuição <- ou =.

Para modificar uma variável existente, podemos usar a mesma função mutate() e especificar pelo que queremos substituir a variável existente. Por exemplo, no próximo trecho de código, vamos modificar a variável Sexo. A variável original tem H para Fêmea e M para Macho, então vamos alterá-la para algo que faça mais sentido:

# Agora vamos atribuir o novo objeto a si mesmo, sobrescrevendo-o.
PRRS <- PRRS %>%  # este é o conjunto de dados que usaremos
  mutate( # usamos a função mutate para criar novas variáveis
    Sex = recode( # A função recode pode ser usada semelhante ao substituir no Excel
      Sex, # vamos substituir a variável Sexo usando o mesmo nome
      H = 'Fêmea',
      M = 'Macho'
    )
  )

Tenha cuidado ao sobrescrever objetos no R, pois não dá para desfazer isso. É importante que seu código esteja organizado e replicável. Assim caso você cometa algum erro você pode facilmente voltar ao seu progresso antes do erro.

2.3 Agrupando e resumindo tabelas

Muitas vezes queremos calcular estatísticas resumidas de nossos dados. Podemos agrupar por uma variável específica (ou até várias variáveis) para examinar se existem diferenças entre grupos.

A forma mais básica de fazer isso é com a função count(), que nos dirá apenas o número de linhas para cada grupo:

# Podemos contar quantas observações para cada nome de variável
PRRS %>% 
  count(Result)
## # A tibble: 2 × 2
##   Result     n
##   <chr>  <int>
## 1 No       986
## 2 Yes      367

A tabela anterior mostra que houve 986 observações com resultado de teste negativo e 367 com resultado de teste positivo. Podemos adicionar várias variáveis para contagem. Agora, iremos contar por Result e Sex:

# Podemos contar com base em várias variáveis
PRRS %>% 
  count(Result, Sex)
## # A tibble: 4 × 3
##   Result Sex       n
##   <chr>  <chr> <int>
## 1 No     Fêmea   737
## 2 No     Macho   249
## 3 Yes    Fêmea   229
## 4 Yes    Macho   138

Também podemos calcular outras estatísticas por grupo. Por exemplo, vamos calcular a média e o desvio padrão da idade por Resultado e Sexo:

PRRS %>%
  group_by(Result, Sex) %>% # Os grupos usados para os dados
  summarise( # A função summarise calcula estatísticas pelos grupos definidos
    meanAge = mean(Age), # Calcula a média da idade
    sdAge = sd(Age) # Calcula o desvio padrão
  )
## # A tibble: 4 × 4
## # Groups:   Result [2]
##   Result Sex   meanAge sdAge
##   <chr>  <chr>   <dbl> <dbl>
## 1 No     Fêmea    39.7  24.8
## 2 No     Macho    22.4  16.7
## 3 Yes    Fêmea    23.6  19.8
## 4 Yes    Macho    15.1  10.3
# PRRS %>%
#   count(Sex, wt = Result)

2.4 Unindo conjuntos de dados

Às vezes, temos diferentes conjuntos de dados que possuem variáveis em comum e queremos integrá-los em um único conjunto de dados para análise posterior. Neste exemplo, temos os conjuntos de dados node_attrib.csv e network.csv.

# Primeiro, importamos os dados -----------
# Importando o conjunto de dados do atributo do nó
nodes <- read.csv("Data/node_attrib.csv")
# Importando o conjunto de dados de movimento
mov <- read.csv("Data/network.csv")

O conjunto de dados mov contém informações sobre o local de origem (id_orig) e destino (id_dest) dos envios de animais. Primeiro, vamos calcular o número total de suínos movidos para cada um dos movimentos de saída e entrada. Para fazer isso, usaremos a função count().

# Obter o número de envios de saída e entrada
Out <- mov %>% # Primeiro, chamamos os dados
  count(id_orig, wt = pigs.moved) %>% # Em seguida, contamos o número de movimentos
  rename(id = id_orig, outgoing = n) # Renomeamos as variáveis

Você perceberá que adicionamos o argumento wt = pigs.moved, em que pigs.moved é uma variável que indica o número de suínos enviados. O argumento wt na função count() nos permite adicionar um peso às contagens. Também usamos a função rename(), que basicamente faz o que o nome sugere, renomeia variáveis nos dados.

Agora, vamos unir os dados com as informações das fazendas contidas no objeto nodes. Para fazer isso, usamos a função left_join():

# Unindo as duas tabelas
# Primeiro, unimos com os envios de saída
farms <- nodes %>% # Este é o objeto principal com o qual faremos a união
  left_join(Out, by ="id") # Precisamos especificar o nome da variável pela qual estamos unindo

Exercício: Agora crie um objeto que seja igual ao Out que acabamos de criar, mas em vez de contar os animais de saída, conte os animais de entrada. Para isso, você pode usar a coluna id_dest. Em seguida, una o novo objeto que você criou com os dados das fazendas. Nomeie a variável que contém o número de suínos movidos como incoming.

# Obter o número de envios de saída e entrada
In <- mov %>% # Primeiro chamamos os dados
  count(id_dest, wt = pigs.moved) %>% # em seguida, contamos o número de movimentos
  rename(id = id_dest, incoming = n) # Renomeamos a variável

## Em seguida, fazemos a união com os envios de entrada
farms <- farms %>%
  left_join(In, by = "id")

As primeiras linhas dos seus dados devem ser assim:

head(farms)
##   id                            name      lat      long farm_type outgoing
## 1  1           Iowa Select Farms Inc 42.50489 -93.26323  sow farm     3528
## 2  2 Stanley Martins Fleckvieh Farms 43.08261 -91.56682  sow farm       NA
## 3  3            Centrum Valley Farms 42.66331 -93.63630   nursery     1087
## 4  4     Hilltop Farms fresh produce 41.71651 -93.90491  sow farm     1606
## 5  5                   Hog Slat Inc. 42.25929 -91.15566       GDU     3440
## 6  6       Safari Iowa Hunting Farms 41.56854 -92.02317       GDU     1073
##   incoming
## 1     1466
## 2     3382
## 3       NA
## 4     3684
## 5     1467
## 6     4491

Observe que temos algumas linhas de envios de saída e entrada com valores NA. Às vezes, os NAs podem interferir em algumas funções, como a soma. No próximo exemplo, vamos resumir os dados e obter os que têm o maior número de movimentos de entrada:

farms %>% # Estes são nossos dados unidos
  group_by(id) %>% # Vamos agrupá-los por id
  summarise( # Vamos realizar algumas estatísticas de resumo
    incoming = sum(incoming, na.rm = T) # observe que adicionamos o argumento na.rm = T
  ) %>%
  arrange(desc(incoming)) %>% # agora vamos ordenar por movimentos de entrada
  head(5) # usamos a função head() para obter as 5 primeiras observações
## # A tibble: 5 × 2
##      id incoming
##   <int>    <int>
## 1    17    79948
## 2     8    19184
## 3    14    12334
## 4     7    11034
## 5    15     4648

3 Exportando os dados

Depois de processar os dados, muitas vezes você deseja exportá-los para que na próxima vez não seja necessário executar todo o código novamente. Você pode exportar para vários formatos, mas o mais comum é um arquivo delimitado por vírgulas (CSV), que pode ser lido no Excel.

write.csv(farms, 'Data/farms.csv', row.names = F)

Este laboratório foi desenvolvido com contribuições de: Jose Pablo Gomez-Vazquez and José Grisi-Filho.
Sinta-se à vontade para usar estes materiais de treinamento em sua própria pesquisa e ensino. Ao utilizar os materiais, agradecemos que sejam atribuídos os devidos créditos. Se você estiver interessado em uma sessão de treinamento, entre em contato: jpgo@ucdavis.edu.