Workshop de R básico

Raquel Divieso

2023-07-10

Olá, hoje vamos inciar nosso curso de introdução ao ambiente R. Este documento ficará disponível para que você volte e utilize quando precisar.

Diretório

Tudo o que queremos abrir no R (ou salvar do R) são obtidos de (ou vão para) um endereço no seu computador. Normalmente este endereço é a pasta “Documentos”, mas podemos checar com o comando:

getwd()
## [1] "C:/Users/raque/OneDrive - ufpr.br/Área de Trabalho/Curso_R_basico_CAEB"

Aqui não precisamos usar nenhum argumento dentro da função para obtermos o que queremos (saber qual é o nosso diretório).

E também podemos mudar a pasta de onde vamos abrir e salvar nossos documentos com a função setwd(” “) sendo o argumento dentro das aspas, nosso novo diretório:

setwd("C:/Users/raque/OneDrive - ufpr.br/Área de Trabalho/Curso_R_basico_CAEB")

Info! Aqui, atenção, o sentido do simbolo de barra sempre deve ser mudado ao copiarmos o diretório da pasta de documentos no Windows.

OBS: comandos podem ser funções já existente no R. Aqui não precisamos usar nenhum argumento dentro da função para obtermos o que queremos (saber qual é o nosso diretório)

Mas também podemos mudar a pasta de onde vamos abrir e salvar nossos documentos:

# setwd("")

E podemos checar o que tem dentro de uma pasta com o comando

dir("C:/Users/raque/OneDrive - ufpr.br/Doutorado/3ºCap/Data/COMBINE/COMBINE_archives")
##  [1] "imputation_error.csv"      "imputation_phylo_1.csv"   
##  [3] "imputation_phylo_181.csv"  "imputation_phylo_209.csv" 
##  [5] "imputation_phylo_219.csv"  "imputation_phylo_30.csv"  
##  [7] "imputation_phylo_729.csv"  "imputation_phylo_756.csv" 
##  [9] "imputation_phylo_825.csv"  "imputation_phylo_83.csv"  
## [11] "imputation_phylo_979.csv"  "mean_error_validation.csv"
## [13] "SD_validation.csv"         "taxonomy_crosswalk.csv"   
## [15] "trait_data_reported.csv"   "trait_data_sources.csv"   
## [17] "trait_databases.csv"

Operações básicas

1+1
## [1] 2
4*7
## [1] 28
3^2
## [1] 9
10/2
## [1] 5
res<- 1+1      #  operador de atribuição <- (podemos usar também o = mas não é muito recomandado)

Atenção, ao criar um objeto com o mesmo nome de outro, ele é substituído pelo último.

res<- 3*10/2

Criando objetos diferentes na mesma linha utilizando o ;

x <- 2; y <- 4; z <- 8
x; y; z
## [1] 2
## [1] 4
## [1] 8

Removendo objetos:

rm(x)  # agora procure o objeto x
rm(y, z) # agora procure os objetos y e z

Vetor lógico:

caracter <- c("Brasil", "Portugal", "Angola", "Macau")
logico <- caracter == "Brasil"
logico
## [1]  TRUE FALSE FALSE FALSE

Vetor lógico numérico:

numeros <- c(2, 5, 10, 1, 5)
logico_n <- numeros > 4
logico_n
## [1] FALSE  TRUE  TRUE FALSE  TRUE
Funções básicas:
sum(1, 8, 79)
## [1] 88
log(4)
## [1] 1.386294
rep(x = 1, times = 7) #x e times são argumentos da função rep
## [1] 1 1 1 1 1 1 1

Para aprendermos a manipular os dados nós vamos utilizar um conjunto de dados chamado COMBINE.

Abrindo a tablela

read.csv() é o comando, o argumento que vai dentro dos parênteses é o nome do objeto que queremos abrir, podemos usar aquele outro comando dir() para ver novamente o nome dos arquivos do seu diretório:

dir() 
##  [1] "~$Workshop_R_1_2_dia.pptx"                                        
##  [2] "Aves_dados.csv"                                                   
##  [3] "Curso de R-2dia.R"                                                
##  [4] "Curso de R.R"                                                     
##  [5] "Curso de R_Rmarkdown.Rmd"                                         
##  [6] "curso_r.pdf"                                                      
##  [7] "Ementa_Introdução à análise de dados ecológicos no ambiente R.pdf"
##  [8] "Flores.pdf"                                                       
##  [9] "incluir.txt"                                                      
## [10] "Parte Teórica.docx"                                               
## [11] "presence_ausence_table.csv"                                       
## [12] "r_bruno.pdf"                                                      
## [13] "Range_size_IUCN.csv"                                              
## [14] "rsconnect"                                                        
## [15] "trait_data_reported.csv"                                          
## [16] "Workshop_R_1_2_dia.pptx"                                          
## [17] "Workshop_R_basico.html"                                           
## [18] "Workshop_R_basico.Rmd"                                            
## [19] "Workshop_R_basico_analises.html"                                  
## [20] "Workshop_R_basico_analises.Rmd"                                   
## [21] "Workshop_R_basico_diversidade.html"                               
## [22] "Workshop_R_basico_diversidade.Rmd"                                
## [23] "Workshop_R_basico_files"
dados<-read.csv("C:/Users/raque/OneDrive - ufpr.br/Área de Trabalho/Curso_R_basico_CAEB/trait_data_reported.csv")

Outros comando muito úteis servem para vermos os nossos dados:

Isso já é interessante para começarmos a entender melhor a utilização dos argumentos dentro das funções. Utilizando o comando ? e depois o nome da função, podemos ver importantes informações sobre a função:

?head

Veja o que vai aparecer aqui no lado direito -> Aqui tem tudo sobre a função e os argumentos que ela precisa ou que podem ser incluidos. Por exemplo o comando “head” necessita do arumento x, que é definido como “an object”, no nosso caso uma tabela. Os seguinted argumentos são opcionais, como o “n”, no qual usamos o número 20 para aparecerem mais linhas do que o defout da função (que no caso é 6).

A função tail mostra o contrário, as últimas linhas da sua tabela.

Outas funções básicas para darmos uma “olhada geral” nos nossos dados:

View(dados) #Abre sua abela em uma nova guia.

str(dados) #o str mostra a estrutura dos nossos dados.
## 'data.frame':    6263 obs. of  60 variables:
##  $ order                   : chr  "Rodentia" "Rodentia" "Rodentia" "Rodentia" ...
##  $ family                  : chr  "Muridae" "Muridae" "Cricetidae" "Cricetidae" ...
##  $ genus                   : chr  "Abditomys" "Abeomelomys" "Abrawayaomys" "Abrawayaomys" ...
##  $ species                 : chr  "latidens" "sevia" "chebezi" "ruschii" ...
##  $ iucn2020_binomial       : chr  "Abditomys latidens" "Abeomelomys sevia" "Abrawayaomys chebezi" "Abrawayaomys ruschii" ...
##  $ phylacine_binomial      : chr  "Abditomys latidens" "Abeomelomys sevia" "Not recognised" "Abrawayaomys ruschii" ...
##  $ adult_mass_g            : num  268.1 57.9 NA 63 265.5 ...
##  $ adult_brain_mass_g      : num  NA 1.49 NA NA NA NA NA NA NA NA ...
##  $ adult_body_length_mm    : num  228 159 NA NA 250 ...
##  $ adult_forearm_length_mm : num  NA NA NA NA NA NA NA NA NA NA ...
##  $ max_longevity_d         : num  NA NA NA NA 852 ...
##  $ maturity_d              : num  NA NA NA NA NA NA NA NA NA NA ...
##  $ female_maturity_d       : num  NA NA NA NA NA NA NA NA NA NA ...
##  $ male_maturity_d         : num  NA NA NA NA NA NA NA NA NA NA ...
##  $ age_first_reproduction_d: num  NA NA NA NA NA NA NA NA NA NA ...
##  $ gestation_length_d      : num  NA NA NA NA NA ...
##  $ teat_number_n           : int  NA 4 NA NA NA NA NA NA NA NA ...
##  $ litter_size_n           : num  NA 1 NA NA 3 ...
##  $ litters_per_year_n      : num  NA NA NA NA 2 NA NA NA NA NA ...
##  $ interbirth_interval_d   : num  NA NA NA NA NA NA NA NA NA NA ...
##  $ neonate_mass_g          : num  NA NA NA NA NA ...
##  $ weaning_age_d           : num  NA NA NA NA NA NA NA NA NA NA ...
##  $ weaning_mass_g          : num  NA NA NA NA NA NA NA NA NA NA ...
##  $ generation_length_d     : num  NA NA NA NA NA NA NA NA NA NA ...
##  $ dispersal_km            : num  0.514 0.221 NA 0.232 0.511 0.384 0.463 0.463 0.463 0.463 ...
##  $ density_n_km2           : num  NA NA NA NA 102 ...
##  $ hibernation_torpor      : int  NA 0 NA 0 0 NA NA 0 NA NA ...
##  $ fossoriality            : int  NA 2 NA NA 2 NA NA 2 NA NA ...
##  $ home_range_km2          : num  NA NA NA NA NA NA NA NA NA NA ...
##  $ social_group_n          : num  NA NA NA NA NA NA NA NA NA NA ...
##  $ dphy_invertebrate       : num  0 19 NA 11 0 0 0 0 0 0 ...
##  $ dphy_vertebrate         : num  0 3 NA 1 0 0 0 0 0 0 ...
##  $ dphy_plant              : num  100 78 NA 88 100 100 100 100 100 100 ...
##  $ det_inv                 : num  0 NA NA NA 0 0 NA 0 NA NA ...
##  $ det_vend                : int  0 NA NA NA 0 0 NA 0 NA NA ...
##  $ det_vect                : int  0 NA NA NA 0 0 NA 0 NA NA ...
##  $ det_vfish               : int  0 NA NA NA 0 0 NA 0 NA NA ...
##  $ det_vunk                : num  0 NA NA NA 0 0 NA 0 NA NA ...
##  $ det_scav                : int  0 NA NA NA 0 0 NA 0 NA NA ...
##  $ det_fruit               : num  0 NA NA NA 0 0 NA 0 NA NA ...
##  $ det_nect                : int  0 NA NA NA 0 0 NA 0 NA NA ...
##  $ det_seed                : num  0 NA NA NA 0 0 NA 0 NA NA ...
##  $ det_plantother          : num  100 NA NA NA 100 100 NA 100 NA NA ...
##  $ det_diet_breadth_n      : int  1 NA NA NA 1 1 NA 1 NA NA ...
##  $ trophic_level           : int  1 2 NA 2 1 1 1 1 1 1 ...
##  $ foraging_stratum        : chr  "Ar" "G" NA "G" ...
##  $ activity_cycle          : int  NA 1 NA NA 1 1 NA 1 NA NA ...
##  $ freshwater              : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ marine                  : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ terrestrial_non.volant  : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ terrestrial_volant      : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ upper_elevation_m       : num  NA 3100 NA NA 4000 2270 3000 5000 NA 2900 ...
##  $ lower_elevation_m       : num  NA 1400 NA NA 0 1800 3000 3700 3800 1100 ...
##  $ altitude_breadth_m      : num  NA 1700 NA NA 4000 470 0 1300 NA 1800 ...
##  $ island_dwelling         : int  NA 0 NA 0 0 NA NA 0 NA NA ...
##  $ island_endemicity       : logi  NA NA NA NA NA NA ...
##  $ disected_by_mountains   : int  NA 0 NA 0 0 NA NA 1 NA NA ...
##  $ glaciation              : int  NA 0 NA 0 0 NA NA 0 NA NA ...
##  $ biogeographical_realm   : chr  "Indomalayan" "Australasian" "Neotropical" "Neotropical" ...
##  $ habitat_breadth_n       : int  1 2 1 1 2 2 2 2 2 2 ...
# Mostra a classe e o comecinho de cada coluna

Repare na utilização do $

Também podemos combinar as coisas

ou podemos nos referir a uma linha específica

dados[6,5]
## [1] "Abrocoma boliviensis"

Podemos também criar um objeto disso:

especie <- dados[6,5]
especie
## [1] "Abrocoma boliviensis"
Vamos criar rapidamente um conjunto de dados para garantir que entendemos a lógica da manipulação

Criando variáveis (que serão colunas) a, b, c e d:

a <- c(12,15,23,44)
b <- c("chá", "café", "cerveja", "suco")
c <- c(TRUE,FALSE,TRUE,FALSE)
d <- c(12.2, 90, 100, 107)
# Join the variables to create a data frame
df <- data.frame(a,b,c,d)
df
##    a       b     c     d
## 1 12     chá  TRUE  12.2
## 2 15    café FALSE  90.0
## 3 23 cerveja  TRUE 100.0
## 4 44    suco FALSE 107.0

Uma coluna só com os nomes:

names(df) <- c('Participante', 'Bebida', 'copo', 'Litros')
df
##   Participante  Bebida  copo Litros
## 1           12     chá  TRUE   12.2
## 2           15    café FALSE   90.0
## 3           23 cerveja  TRUE  100.0
## 4           44    suco FALSE  107.0

Info! Aproveitando para entender melhor o c() e os TRUE/FALSE!.

df[, c('bebida', 'Litros')]
## Error in `[.data.frame`(df, , c("bebida", "Litros")): colunas indefinidas selecionadas

Qual o erro?

Adição de colunas:

periodo<- c("M", "M", "T", "MT")
df$periodo <- periodo

df
##   Participante  Bebida  copo Litros periodo
## 1           12     chá  TRUE   12.2       M
## 2           15    café FALSE   90.0       M
## 3           23 cerveja  TRUE  100.0       T
## 4           44    suco FALSE  107.0      MT
Voltando à outras formas de checarmos os dados:

Qual a dimensão dos nossos dados:

mean(dados$adult_mass_g) 
## [1] NA

erro? é porque temos vários dados faltantes na nossa tabela. Estes dados normalmente são preenchidos com NA

head(dados$adult_mass_g) #veja o NA na 3º linha
## [1] 268.09  57.89     NA  62.99 265.50 158.00

Temos duas opções, vou deletamos todas as linhas com NA ou utilizamos um argumento nas funções na.rm = T:

mean(dados$adult_mass_g, na.rm = T)
## [1] 130777.5
#A média dos tamanhos de corpo entre todos os mamíferos é 130777.5 gramas.
median(dados$adult_mass_g, na.rm = T) #e a mediana é 79.18
## [1] 79.18
min(dados$adult_mass_g, na.rm = T) #o valor mínimo é 1.6 gramas.
## [1] 1.6
max(dados$adult_mass_g, na.rm = T) #o valor máximo da coluna é 1.49e+08, que é 149000000
## [1] 1.49e+08

E de qual espécie esse valor máximo?

Corresponde à linha 385

dados$iucn2020_binomial[385]
## [1] "Balaenoptera musculus"

Visualizando os dados

O histograma é uma ótima forma de plotar nossos dados, para isso usamos a função hist:

hist(dados$litter_size_n)

E também podemos plotar uma caracteristica contra outra

plot(dados$adult_mass_g, dados$litter_size_n)

Ficou bom? Quando separados por uma virgula os plot será sempre a variável x contra a variável y.

Podemos utilizar os dados logaritmizados, utilizando a função log:

plot(log(dados$adult_mass_g), log(dados$litter_size_n))

E aqui já começamos a usar uma função dentro de outra! Logo vamos aprender a testar se existe uma correlação significativa entre os dados, mas vamos por partes.

Outra coisa bem interessante é que podemos editar as tabelas abertas dentro do R Para não ficarmos sempre transformando o tamanho de corpo, podemos incluir uma coluna na nossa tabela com isso.

dados$log_adult_mass <- log(dados$adult_mass_g)

Ou podemos alterar uma determinada linha

dados$genus[4] #"Abrawayaomys"
## [1] "Abrawayaomys"
dados$genus[4] <- "novo_nome"
head(dados$genus)
## [1] "Abditomys"    "Abeomelomys"  "Abrawayaomys" "novo_nome"    "Abrocoma"    
## [6] "Abrocoma"

mas voltamos ao que era

dados$genus[4]<- "Abrawayaomys"

Outra informação interessante no campo de ajuda das funções são os exemplos disponíveis no final da página. Por exemplo, para fazermos um boxplot:

?boxplot

Vamos pegar o primeiro exemplo:

boxplot(count ~ spray, data = InsectSprays, col = "lightgray")

Estes dados plotados são conjuntos de dados disponíveis no R (InsectSprays) justamete para fazermos isso. Notem que não precisaram ser usados nenhum $ para nos referirmos às colunas, porque os dados foram identificados no argumento data. Uma função prática disso é que podemos ver como os dados devem estar para plotarmos da mesma forma:

head(InsectSprays$count)
## [1] 10  7 20 14 14 12
head(InsectSprays$spray)
## [1] A A A A A A
## Levels: A B C D E F

Aqui temos a classe de objetos “levels”. Portanto sabemos que um boxplot deve ter uma variável de contagem (eixo y) e outra de níveis (eixo x). Neste caso o ~ tem a função de separar os argumentos e testa um contra o outro, mas sempre inverte a ordem de quando usamos vírgula.

mudando a cor

boxplot(count ~ spray, data = InsectSprays, col = "red")




Em vários lugares podemos encontrar cores para serem usadas no R! http://www.stat.columbia.edu/~tzheng/files/Rcolor.pdf Ou outros sites que trazem muitas opções: https://www.colorhexa.com/ procure neste site a cor #dc0361 e veja as opções.

boxplot(count ~ spray, data = InsectSprays, col = "#dc0361")

O mesmo podemos fazer para outros gráficos que já aprendemos e incluir mais algumas coisas:

plot(dados$gestation_length_d, log(dados$neonate_mass_g))

plot(dados$gestation_length_d, log(dados$neonate_mass_g), xlab="Tempo de gestação", ylab="Massa do neonato")

plot(dados$gestation_length_d, log(dados$neonate_mass_g), xlab="Tempo de gestação", ylab="Massa do neonato", main= "Meu gráfico lindo" )

plot(dados$gestation_length_d, log(dados$neonate_mass_g), xlab="Tempo de gestação", ylab="Massa do neonato", main= "Meu gráfico lindo", pch=20, col="#af058e" )

Você pode mudar os valores do argumento pch e ver diferentes tipos de pontos disponíveis: http://www.sthda.com/english/wiki/r-plot-pch-symbols-the-different-point-shapes-available-in-r

plot(dados$gestation_length_d, log(dados$neonate_mass_g), xlab="Tempo de gestação", ylab="Massa do neonato", main= "Meu lindo gráfico", pch=21,  col="#a80436", bg="#e10649", lwd=2, cex=1.5)

bg é a cor do preenchimento, cex é o tamanho dos pontos, lwd é tamanho da borda.

identify(x, y, labels=dados$binomial)

Identificando um ponto ou um conjunto de pontos em um gráfico.

  • locator(n) A função locator localiza o valor de x e y de n pontos. Se quero identificar 3 pontos no meu último plot utilizo:
locator(3)

E clico com o botão direito do mouse sobre os pontos desejados.

  • identify(n) Já o comando identify, identifica uma determinada identificação dos pontos, não só sua posição.
identify(dados$gestation_length_d, log(dados$neonate_mass_g), labels=dados$iucn2020_binomial, n=4)

Mas para pontos muito grandes n]ao funciona bem. Podos refazer o plot com pontos menores para testar.

Salvando imagens

tiff("Meu grafico lindo", )
plot(dados$gestation_length_d, log(dados$neonate_mass_g), xlab="Tempo de gestação", ylab="Massa do neonato", main= "Meu lindo gráfico", pch=21,  col="#a80436", bg="#e10649", lwd=2, cex=1.5)
dev.off

Outras opções são - bmp - jpeg - png - pdf E os argumentos width e height podem ser alterados.

Voltando aos boxplots, nos nossos dados também podemos usar este tipo de visualização.

Vamos ver a relação entre o tamanho do range size e as regiões biogeográficas entre as espécies

bp <- boxplot(log(dados$home_range_km2) ~ dados$biogeographical_realm, col ="#f8af08")
## Warning in bplt(at[i], wid = width[i], stats = z$stats[, i], out =
## z$out[z$group == : Outlier (-Inf) no boxplot 1 não desenhado
## Warning in bplt(at[i], wid = width[i], stats = z$stats[, i], out =
## z$out[z$group == : Outlier (-Inf) no boxplot 10 não desenhado
## Warning in bplt(at[i], wid = width[i], stats = z$stats[, i], out =
## z$out[z$group == : Outlier (-Inf) no boxplot 15 não desenhado
## Warning in bplt(at[i], wid = width[i], stats = z$stats[, i], out =
## z$out[z$group == : Outlier (-Inf) no boxplot 16 não desenhado
## Warning in bplt(at[i], wid = width[i], stats = z$stats[, i], out =
## z$out[z$group == : Outlier (-Inf) no boxplot 17 não desenhado
## Warning in bplt(at[i], wid = width[i], stats = z$stats[, i], out =
## z$out[z$group == : Outlier (-Inf) no boxplot 19 não desenhado
## Warning in bplt(at[i], wid = width[i], stats = z$stats[, i], out =
## z$out[z$group == : Outlier (-Inf) no boxplot 20 não desenhado

Nestes casos uma coisa útil é você criar um data frame apenas com os dados que vamos usar

df<- dados$home_range_km2
names(df)<- dados$order

Quando nossos dados possuem apenas uma variável é possível dar um nome pra cada linha, como fizemos, usando a função names. Quando temos mais de uma coluna, usamos a função row names

Podemos excluir as linhas com NA usando a função na.omit

df<-na.omit(df)

Para poucos níveis no eixo x um boxplot simples funciona bem, mas para muitos, como é o nosso caso não. Vamos complicar um pouquinho mais para vermos como “girar” os nomes no eixo x e outras adaptações da figura

A função par ajusta as margens da figura, quando rodamos o R guarda a informação para utilizar nos seguintes plots.

par(mar = c(6.1, 4.1, 4.1, 4.1), # mudando as margens
    lwd = 1.2, # aumentando o traço de cada boxplot
    cex.axis = 1.2 # aumentando o tamanho da legenda do eixo
)

Vamos usar duas cores diferentes

bp <- boxplot(log(df)~names (df), col = c("#ac4105", "#05ac94"), las=2, xlab="", ylab="Home range (Km²)")
## Warning in bplt(at[i], wid = width[i], stats = z$stats[, i], out =
## z$out[z$group == : Outlier (-Inf) no boxplot 20 não desenhado

Podemos deixar o texto no eixo x apenas inclinado. Essas coisas são um pouco mais complexas de fazer. Uma dica de exercício para depois: tente conversar com o chatGTP e pedir ajuda para deixar os nomes inclinados.

Filtrando dados

A forma mais simples de filtrar dados é utilizando a função subset. Vamos criar um dataframe apenas com espécies da ordem chiroptera:

chiroptera<- subset(dados, order=="Chiroptera")
chiroptera[1:5,c(1,5)] #quero que apareça apenas as linhas de 1:5 e as colunas 1 e 5.
##         order   iucn2020_binomial
## 21 Chiroptera Acerodon celebensis
## 22 Chiroptera    Acerodon humilis
## 23 Chiroptera    Acerodon jubatus
## 24 Chiroptera   Acerodon leucotis
## 25 Chiroptera   Acerodon mackloti

Também podemos filtrar valores. POr exemplo, quero uma dataframe com todos os animais com menos de 5 gramas:

peq_mam<- subset(dados, adult_mass_g<= 5)

#Plotando os dados filtrados:
hist(peq_mam$adult_mass_g, breaks = 30, xlab="Massa do adulto (g)", ylab="Frequência", col="rosybrown2", border="rosybrown4", main=" ", lwd=2)

Também podemos filtrar um conjunto de dados baseado em uma regra combinada:

Por exemplo, queremos criar uma tabela com espécies que são tanto marinhas quanto de água doce:

Primeiro checamos as variáveis de cada coluna:

table(dados$freshwater) 
## 
##    0    1 
## 5786  144
table(dados$marine)
## 
##    0    1 
## 5793  137

Queremos espécies com a ocorrência “1”.

Podemos checar também a classe de objeto nessas colunas, para usarmos charactere ou vetor:

class(dados$marine)
## [1] "integer"
class(dados$freshwater)
## [1] "integer"

Ambas variáveis são da classe “integer”, ou seja, não precisamos tratar os dados como characteres.

aquaticas<- subset(dados, marine==1 & freshwater==1)

dim(aquaticas) #A função dim mostra a dimensão da sua tabela, linhas e colunas respectivamente.
## [1] 19 61

O pacote dplyr

library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union

Podemos usar algumas funções do pacote que facilitam a manipulação de dados

dados_2<- select(dados, order, iucn2020_binomial, density_n_km2, det_diet_breadth_n,  biogeographical_realm)

Também podemos mudar o nome das colunas de diferentes formas.

# R base
colnames(dados_2)<- c("ordem", "specie", "densidade", "dieta", "biogeog")

# Com dplyr - podemos trocar todas as colunas ou apenas uma com maior facilidade:
dados_2<- rename(dados_2, binomial=specie)
colnames(dados_2) #checando o nome das colunas
## [1] "ordem"     "binomial"  "densidade" "dieta"     "biogeog"

Organizando uma tabela toda com base em uma coluna

Do menor para o maior é o defout:

dados_2<-arrange(dados_2, densidade)

Ou o contrário, em ordem decrescente:

dados_2<-arrange(dados_2, desc(densidade))

Combinar conjuntos de dados

Se nós temos dois conjuntos de dados para muitas espécies e queremos combinar ambos baseado no número de espécies, podemos usar a função merge.

Vamos abrir outro conjunto de dados. São áreas de distribuição calculadas a partir dos dados disponíveis na IUCN. Queremos ver se os dados de home range nos dados do COMBINE são complementares a estes dados:

#Novamente abrindo os dados

area<- read.csv("C:/Users/raque/OneDrive - ufpr.br/Área de Trabalho/Curso_R_basico_CAEB/Range_size_IUCN.csv")
  • Faça um head para vermos como os dados estão.

  • Os dados de distribuição da IUCN possuem uma classificação, vamos somar as areas que provavelmente correspondem a uma estimativa mais precisa. POdemos não somar as áreas com incerteza (possiveis ou prováveis) e manter só as áreas com residência.

Vamos somar: # Extant_.resident. (coluna 2) # Extant_._Introduced_.resident. (coluna 3) # Extant_._Origin_Uncertain_.resident. (coluna 4) # Extant_._Reintroduced_.resident. (coluna 5)

Vamos criar uma nova coluna com a soma destas três colunas. Lembrando que temos muitas células como NA.

area$area_iucn <-  rowSums(area[ ,2:5], na.rm=T)
hist(area$area_iucn, breaks = 50)

Para combinarmos os dois conjuntos de dados, precisamos que a coluna usada como “match” seja igual em ambas tabelas. Vamos checar se os nomes estão escritos de forma igual:

head(dados$iucn2020_binomial)
## [1] "Abditomys latidens"   "Abeomelomys sevia"    "Abrawayaomys chebezi"
## [4] "Abrawayaomys ruschii" "Abrocoma bennettii"   "Abrocoma boliviensis"
head(area$Binomial)
## [1] "Microgale_jobihely"         "Neamblysomus_gunningi"     
## [3] "Eremitalpa_granti"          "Amblysomus_septentrionalis"
## [5] "Calcochloris_obtusirostris" "Amblysomus_marleyi"

O caractere separando o nome científico das espécies está diferente. Então, vamos mudar “_” por espaço nos dados de área usando a função gsub:

area$Binomial <- gsub("_", " ", area$Binomial)

head(area$Binomial) #checando se funcionou
## [1] "Microgale jobihely"         "Neamblysomus gunningi"     
## [3] "Eremitalpa granti"          "Amblysomus septentrionalis"
## [5] "Calcochloris obtusirostris" "Amblysomus marleyi"

Agora sim podemos combinar os dados. Se as duas colunas de match têm o mesmo nome, só incluimos o nome em by= Mas no nosso caso os nomes estão diferentes, então vamos usar a função intercept dentro do argumento by. Uma outra opção é usarmos a função rename para igualar os nomes.

dados <- merge(dados, area , by.x = "iucn2020_binomial", by.y = "Binomial",)

Outras opções de união: manter todas as ocorrências (all=TRUE), manter todas as ocorrências que possuem um valor em (all.x=TRUE) e manter todas as que possuem vamor em y (all.y=TRUE).

  • teste1 <- merge(dados, area , by.x = “iucn2020_binomial”, by.y = “Binomial”, all=TRUE)
  • teste2 <- merge(dados, area , by.x = “iucn2020_binomial”, by.y = “Binomial”, all.x=TRUE)
  • teste3 <- merge(dados, area , by.x = “iucn2020_binomial”, by.y = “Binomial”, all.y=TRUE)
  • teste4 <- merge(dados, area , by.x = “iucn2020_binomial”, by.y = “Binomial”, all=FALSE)

Vamos resumir nossa tabela:

dados <- select(dados, order, iucn2020_binomial, home_range_km2, area_iucn)

Contabilizando NAs nas colunas:

table(is.na(dados$home_range_km2))
## 
## FALSE  TRUE 
##   795  5050
table(is.na(dados$area_iucn))
## 
## FALSE 
##  5845

Na realidade teremos 795 ocorrências para fazer nossa checagem:

plot(log(dados$home_range_km2), log(dados$area_iucn))

Para muitas espécies existe uma correlação direta, mas para outras tantas os dados da IUCN estão bem diferentes.


Para finalizar, vamos aprender mais duas coisas úteis no R: a simulação de dados e a utilização das condições if e else e da função ifelse.

Simulação de dados

Quero testar se o diâmetro das arvores em um determinado fragmento florestal diminui com a distância da borda do fragmento.

Estas são algumas opções de simulação de dados:

seq(1, 20)
##  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
seq(0, 20, by = 5)
## [1]  0  5 10 15 20
LETTERS[seq( from = 1, to = 10 )]
##  [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J"
letters[seq( from = 1, to = 10 )]
##  [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
sample(8:200, 10)
##  [1]  94  89 180  52 129 166  62 163 143  75
sim<-runif(n = 100, min = 0, max = 1)
hist(sim)

sim_norm <- rnorm(n = 100, mean=10)
hist(sim_norm)

Criar um dataframe de dados simulados com 100 linhas e três colunas:

df <- data.frame(diametro = rnorm(n = 100, mean=6),
                 metros_da_borda = sample(0:1000, size =100 ),
                 spp = NA,
                 stringsAsFactors = FALSE)

# Vetor com os nomes a serem aleatorizados:
nomes <- c("spp1", "spp2", "spp3", "spp4", "spp5")

# Aleatorizar os nomes e atribuir à coluna SPP
df$spp <- sample(nomes, size =  100, replace = TRUE)

Gerando algumas cores para nosso seguinte plot. Para isso vamos usar a paleta rainbow, dentro da dunção palette

cores<-palette(rainbow(6)) 

Colorindo cada espécie com uma cor diferente.

plot(df$diametro, df$metros_da_borda, pch=16, col = cores[factor(df$spp)])

Função ifelse

Agora, vamos criar uma outra coluna para testarmos as funções ifelse:

df$altura<- rnorm(n = 100, mean=8)

Eu quero uma coluna que me informe se a planta é juvenil ou adulta, dependendo da relação tamanho-diâmetro (situação totalmente hipotética):

df$estagio<-NA  #criando uma coluna 

ifelse((df$diametro/df$altura) <= 0.5, df$estagio<-"juvenil", df$estagio<-"adulto")
##   [1] "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto" 
##   [8] "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto" 
##  [15] "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto" 
##  [22] "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto" 
##  [29] "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto" 
##  [36] "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto" 
##  [43] "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto" 
##  [50] "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto" 
##  [57] "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto" 
##  [64] "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto" 
##  [71] "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "juvenil"
##  [78] "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto" 
##  [85] "adulto"  "adulto"  "adulto"  "juvenil" "adulto"  "adulto"  "adulto" 
##  [92] "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto"  "adulto" 
##  [99] "adulto"  "adulto"

Criando uma função

minha_fun<-function(x, y){

x + y*x

}

Aplicando a função

minha_fun(4, 10)
## [1] 44