Essa é uma pequena análise explorando os dados de espécies nativas da flora brasileira. Esta é a primeira parte de uma série de três análises integrando dados do projeto Flora 2020 do Jardim Botânico do Rio de Janeiro (JBRJ), Global Biodiversity Information Facility (GBIF) e a Lista Vermelha da IUCN. O objetivo dessa série é analisar algumas informações jogadas em minha nuvem de “coisas para explorar da flora” que não tive tempo enquanto ainda trabalhando na área, ao passo que treino/refino algumas técnicas de análise de dados e estatística em geral e ainda guardo alguns códigos e pipelines úteis para outras instâncias.
Esta primeira parte visa extrair, manipular e limpar dados da flora 2020, além de constuir algumas visualizações dos dados. Uma segunda parte, mais voltada para análises estatísticas e desenho experimental já está em andamento e uma terceira já está planejada para ser conduzida em seguida. Todas estas análises estão sob constante revisão, sofrendo constantes alterações
Estou usando exclusivamente R nessa série.
Esta análise está dividida em duas seções:
Principais pacotes utilizados:
tidyverse
: Conjunto de pacotes com ferramentas de análise, transformação e visualização de dados.lubridate
: Manipulação de datas e hora´.patchwork
: Combinar gráficos separados de maneira simples.ggrepel
: Arranjo organizado de labels em plots.forcats
: Manipulação mais intuitiva de variáveis categóricas.jsonlite
: Parsing de entradas json.PNWColors
: Paleta de cores.ggExtra
: Funções para aprimorar o ggplot2.cowplot
: Plotar gráficos em grid.Ademais, escrevi algumas funções que auxiliaram na transformação desses dados, algumas explicitei no próprio documento, outras mais extensas não, mas todas podem ser encontradas no repositório do projeto em meu github.
Os dados utilizados se referem àqueles gerados pelo projeto Flora 2020 do JBRJ. O principal objetivo desse projeto é catalogar a maior quantidade de dados possíveis da flora brasileira, no âmbito da “Estratégia Global para Conservação de Plantas (GSPC)”. Dentre os dados disponíveis, quero compilar e explorar àqueles pertencentes à quatro grandes grupos:
Essas informações encontram-se armazenadas em uma série de arquivos organizados como tabelas interrelacionais. Se encontram no formato Darwin Core (DwC-A), um padrão de formatação de dados da biodiversidade. O projeto Flora 2020 armazena informações para todos níveis taxonômicos, mas aqui pretendo analisar apenas o nível de espécie.
Antes de mais nada, vou carregar todos pacotes e funções que irei utilizar daqui em diante:
# primeiro os pacotes já citados:
library(tidyverse)
library(lubridate)
library(patchwork)
library(ggrepel)
library(forcats)
library(PNWColors)
library(jsonlite)
library(ggExtra)
library(plotly)
library(cowplot)
# funções que eu escrevi para a analise
source("scripts/flora_2020_analysis_functions.R")
pal=pnw_palette("Bay",5, type = "discrete")
Agora é baixar os dados direto do ipt, que estão em um zip:
rl <- 'http://ipt.jbrj.gov.br/jbrj/archive.do?r=lista_especies_flora_brasil&v=393.224' # url do aquivo
download.file(url, destfile = "data.zip", mode="wb") # download
unzip(zipfile = "data.zip",exdir = "data") # extração na pasta "data"
As informações que busco estão nos arquivos .txt do DwC-A:
grep(".txt",list.files("data/"),value=TRUE)
## [1] "distribution.txt" "reference.txt"
## [3] "resourcerelationship.txt" "speciesprofile.txt"
## [5] "taxon.txt" "typesandspecimen.txt"
## [7] "vernacularname.txt"
Quero compilar informações de 5 arquivos:
taxon.txt: contém as informações mais básicas que preciso para começar a análise, como as informações taxonômicas das entradas e os autores das descrições. Lembrando que os dados desse arquivo se aplicam a todos níveis taxonômicos contemplados no projeto (e.g. reino e gênero).
reference.txt: contém informações relativas à descrição dos taxa (e.g. ano e autor).
distribution.txt: informa se os taxa são endêmicos ou não e em que domínios fitogeográficos ou estados brasileiros eles ocorrem.
specieprofile.txt: contém informações acerca da forma de vida, habitat e tipo de vegetação de ocorrência dos taxa.
vernacular.txt: contém os nomes populares das espécies.
Não vou usar os demais arquivos, typesandspecimen.txt
e resourcerelationship.txt
, pois eles se referem a dados não utilizados em minhas análises. Sempre vale lembrar também que a informação que busco nessa análise muito provavelmente não existe para todas espécies da amostra.
Vou então ler todos esses arquivos:
taxon <- read_delim(file="data/taxon.txt", delim = "\t")
distribution <- read_delim(file="data/distribution.txt", delim = "\t")
references <- read_delim("data/reference.txt", delim = "\t")
vernacular <- read_delim("data/vernacularname.txt", delim = "\t")
profile <- read_delim("data/speciesprofile.txt", delim = "\t")
O que quero fazer em seguida é compilar apenas as informações que preciso de cada um desses arquivos, armazenando tudo em um único data frame que vou chamar de df_master
.
Para esta análise, quero trabalhar apenas com espécies nativas e sem problemas nomenclaturais de qualquer tipo (não são sinônimos, espécies naturalizadas ou exóticas/invasivas, nem representam nomes em desuso). Para fazer isso vou começar filtrando as colunas taxonomicStatus
, nomenclaturalStatus
e taxonRank
da tabela taxon
.
A coluna taxonomicStatus
indica se um registro se refere a um nome aceito ou sinônimo:
unique(taxon$taxonomicStatus)
## [1] "NOME_ACEITO" "SINONIMO" NA
Já a coluna nomenclaturalStatus
indica se o nome em questão é correto ou se existe algum tipo de problema associado a ele:
unique(taxon$nomenclaturalStatus)
## [1] "NOME_CORRETO" NA
## [3] "NOME_LEGITIMO_MAS_INCORRETO" "NOME_CORRETO_VIA_CONSERVACAO"
## [5] "VARIANTE_ORTOGRAFICA" "NOME_ILEGITIMO"
## [7] "NOME_NAO_EFETIVAMENTE_PUBLICADO" "NOME_NAO_VALIDAMENTE_PUBLICADO"
## [9] "NOME_MAL_APLICADO" "NOME_REJEITADO"
## [11] "NOME_APLICACAO_INCERTA"
Um taxon pode não ter tido seu nome publicado ainda ou pode ter sido catalogado de forma incorreta por algum motivo. Vou seguir mantendo apenas espécies que tem nomes corretos sem qualquer tipo de problema.
Finalmente, a tabela taxonRank
indica o nível taxonômico do registro:
unique(taxon$taxonRank)
## [1] "ORDEM" "FAMILIA" "GENERO" "ESPECIE" "VARIEDADE"
## [6] "SUB_ESPECIE" "CLASSE" "TRIBO" "SUB_FAMILIA" "DIVISAO"
## [11] "FORMA"
Faço então todos filtros que preciso e mantenho na tabela taxon
apenas as espécies que seguem meus critérios:
taxon <- taxon %>%
filter(taxonomicStatus == "NOME_ACEITO", # apenas nomes aceitos
nomenclaturalStatus == "NOME_CORRETO", # apenas nomes corretos
taxonRank == "ESPECIE") # apenas nomes que se referem a espécies
Ainda assim, ainda não filtrei as espécies nativas da amostra, dado que essa informação não está contida na tabela taxon
, pois está na arquivo distribution
, especificamente na coluna establishmentMeans
. Para filtrar isso posso usar os id´s da tabela taxon, que agora contém apenas as espécies com nome correto:
# filtro entradas nativas na tabela distribution
distribution <- distribution %>% filter(establishmentMeans == "NATIVA")
# extraio as id´s que se referem à espécies nativas
ids_native <- unique(distribution$id)
# filtro tabela taxon novamente, mantendo apenas espécies nativas
taxon <- taxon %>% filter(id %in% ids_native)
A tabela taxon
agora está do jeito que quero, apenas com espécies nativas e com nomes livres de problemas. Essa tabela vai formar a base do df_master
, então, a partir dela, vou selecionar apenas minhas variáveis de interesse e incrementar aos poucos com novas informações das demais tabelas que ainda me resta analisar:
# criando df_master a partir das variáveis de interesse da colunas taxon
df_master <- taxon %>%
select(id, # id das especies
scientificName, # nome científico
higherClassification, # backbone taxonomico
family) # familia
Vale dar uma olhada geral na estrutura da tabela:
glimpse(df_master)
## Rows: 38,079
## Columns: 4
## $ id <dbl> 264, 280, 285, 301, 315, 319, 342, 343, 439, 440…
## $ scientificName <chr> "Adiscanthus fusciflorus Ducke", "Andreadoxa fla…
## $ higherClassification <chr> "Flora;Angiospermas;Rutaceae A.Juss.;Adiscanthus…
## $ family <chr> "Rutaceae", "Rutaceae", "Rutaceae", "Rutaceae", …
A tabela contém a informação de 38079 espécies nativas da flora brasileira, mas ainda falta informação a ser compilada.
Agora vou extrair as demais informações seguindo a lógica utilizada na tabela taxon
, mas usando a função match
. Especificamente, quero puxar os dados abaixo das espécies:
A tabela references
contém o ano de descrição e autoria das mesmas para as espécies, respectivamente nas colunas date
e creator
. Ao incluir essas informações no df_master
, vou criar nomes mais intuitivos para as colunas:
ids_master <- df_master[["id"]] # pego as ids das espécies contidas no df_master
# nova coluna criada com os anos de descrição das espécies
df_master[["desc_year"]] <- references$date[match(ids_master,references$id)]
# mesma coisa com os autores
df_master[['descriptor']] <- references$creator[match(ids_master,references$id)]
Antes de seguir em frente, já vou limpar a coluna de datas que apresenta alguns problemas:
unique(df_master$desc_year)[250:300]
## [1] "1994/1995"
## [2] "107"
## [3] "1809"
## [4] "2018"
## [5] "147"
## [6] "1868-70"
## [7] "393"
## [8] "187"
## [9] "2019"
## [10] "1831-1834"
## [11] "1785"
## [12] "1796"
## [13] "1814"
## [14] "1794"
## [15] "189"
## [16] "194"
## [17] "1989/1990"
## [18] "1764"
## [19] "1071"
## [20] "216"
## [21] "1967-1969"
## [22] "1886-1888"
## [23] "1772"
## [24] "doi:10.1594/PANGAEA.85167 4196946_35_0"
## [25] "285"
## [26] "no prelo"
## [27] "3013"
## [28] "1969."
## [29] "1992."
## [30] "1828."
## [31] "2006."
## [32] "1991."
## [33] "2010."
## [34] "212"
## [35] "1"
## [36] "213"
## [37] "454"
## [38] "461"
## [39] "60"
## [40] "262"
## [41] "35"
## [42] "191"
## [43] "2994"
## [44] "467"
## [45] "906"
## [46] "199"
## [47] "1793"
## [48] "2020"
## [49] NA
## [50] NA
## [51] NA
Vou ser um pouco conservador na minha abordagem e eliminar tudo que não tem mais de quatro caracteres (já que a coluna está formatada como string):
# função para limpar as datas:
# se data for NA, mantem como NA
# se data tiver quatro caracteres, mantem data
# se não, retorna NA
clean_dates <- function(x){
if(is.na(x)){return(NA)
break
}
if (nchar(x) == 4){return(x)}
else{return(NA)}}
# vou aplicar a função para a coluna toda e converter o tipo para numerico
# tipo numerico vai converter para NA o que tiver letra dentre os quatro char
df_master[['desc_year']] <- df_master[['desc_year']] %>% # coluna
map(clean_dates) %>% # aplicar função
as.numeric() # deixar como tipo numerico
Vou dar uma olhada nas estatísticas sumarizadas da coluna:
summary(df_master[['desc_year']])
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 1071 1893 1976 1948 2003 3013 14661
O mínimo e o máximo ainda estão bem esquisitos, vou manter apenas datas que se encontram em um intervalo de tempo razoável: entre 1700 (pouco antes do estabelecimento do sistema lineniano) e 2020. O resto vou converter para NA.
year_fix <- function(x){
if (is.na(x)){return(NA)} # se o ano é NA, retorna NA
if (x<1700 || x>2020){return(NA)}else{return(x)} # valores fora do intervalo retornam NA
}
# recriando coluna aplicando a função à coluna existente
df_master <- df_master %>% mutate(desc_year = modify(df_master[['desc_year']],year_fix))
Os valores agora parecem fazer mais sentido:
sort(unique(df_master[['desc_year']]))
## [1] 1752 1753 1755 1756 1759 1760 1762 1763 1764 1765 1766 1767 1768 1771 1772
## [16] 1773 1775 1781 1782 1783 1784 1785 1786 1788 1789 1791 1792 1793 1794 1796
## [31] 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811
## [46] 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826
## [61] 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841
## [76] 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856
## [91] 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871
## [106] 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886
## [121] 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901
## [136] 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916
## [151] 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931
## [166] 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946
## [181] 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961
## [196] 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976
## [211] 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991
## [226] 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006
## [241] 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020
Agora vou adicionar as informações da tabela distribution
. A coluna location_id
contém a informação acerca dos estados no Brasil onde as espécies ocorrem. Cada id é repetido por número estado de ocorrência:
distribution %>% filter(id == 264)
Essa espécie ocorre no Pará, Amazonas e Acre. Vou inserir essas informações para as espécies no df_master
de modo elas fiquem agrupadas em uma única string, usando um separador:
# nessa função, indico qual o separador que vou usar depois de especificar uma id (x),
# coluna e tabela.
collapse_column <- function(x,column,df,split_character=";"){
df_temp <- df %>% filter(id == x)
if (length(rownames(df_temp)) == 0){return(NA)} else {
output <- paste(df_temp[[column]],collapse = split_character)
return(output)
}
}
# crio uma nova coluna 'states' com as informações de estado de ocorrência
df_master[['states']] <- map(ids_master,collapse_column,column="locationID",df=distribution) %>%
gsub("BR-","",.) # removendo o prefixo para ficar mais limpo
E a coluna fica com uma cara assim:
df_master['states'] %>% slice(1:10)
Agora vou extrair as informações de domínios de ocorrência e endemismo, ambas contidas nas colunas occurrenceRemarks
, ainda da tabela distribution
. Essas informações estão armazenadas no formato json:
distribution$occurrenceRemarks[5000]
## [1] "{\"endemism\":\"Não endemica\",\"phytogeographicDomain\":[\"Amazônia\"]}"
Vou extrair nesse formato mesmo e fazer o parsing mais adiante:
df_master['distribution']<-distribution$occurrenceRemarks[match(ids_master,distribution$id)]
As informações ecológicas estão armazenadas de maneira semelhante, na tabela profile
, em uma coluna de nome não muito intuitivo: lifeForm
. Vou incluir esses dados direto em uma coluna do df_master
e fazer o parsing depois.
df_master['profile'] <- profile$lifeForm[match(ids_master,profile$id)]
Já os nomes vernaculares das espécies encontram-se na coluna vernacularName
da tabela vernacular
, armazenados da mesma forma que os estados de ocorrência, então vou usar a função que utilizei no caso dos estados, gerando uma nova coluna no df_master
chamada vernacular_name
:
df_master['vernacular_name'] <-
map(ids_master,collapse_column,
column="vernacularName",df=vernacular) %>%
unlist()
A maior parte dos dados que preciso já está no df_master
, mas ainda preciso fazer o parsing daquelas colunas no formato json. Vou chamar uma função que fiz para lidar com isso, o que essa função faz é quebrar em colunas a informação contida nos json, por exemplo, isso aqui:
df_master$distribution[1507:1508]
## [1] "{\"endemism\":\"Endemica\",\"phytogeographicDomain\":[\"Mata Atlântica\"]}"
## [2] "{\"endemism\":\"Endemica\",\"phytogeographicDomain\":[\"Mata Atlântica\"]}"
Toma o formato abaixo, onde as chaves se tornam colunas com a informação pertinente:
json_parser(df_master$distribution[1507:1508])
Então uso a função nas colunas inteiras que contém informação como JSON e este problema está resolvido:
# parsing da coluna distribution
# cada chave vai ser uma coluna nova
df_master <- json_parser(df_master$distribution) %>%
bind_cols(df_master) %>% # incluo a informação no df_master
select(-distribution) # remove a coluna com os JSON, agora obsoleta
# mesma coisa com a coluna profile
df_master <- json_parser(df_master$profile) %>%
bind_cols(df_master) %>%
select(-profile,-habitat) # alem de remover a coluna obsoleta, tirei a coluna da chave habitat
# que não vai ser utilizada na análise
Essa operação criou três novas colunas no df_master
: lifeForm
e vegetationType
, que vieram da tabela distribution
e as colunas endemism
e phytogeographicDomain
que vieram da tabela profile
:
head(df_master)
Ainda me resta extrair apenas o que quero da coluna higherClassification
, que contém informações taxonômicas das espécies e está formatada dessa maneira:
head(df_master[["higherClassification"]])
## [1] "Flora;Angiospermas;Rutaceae A.Juss.;Adiscanthus Ducke;Adiscanthus fusciflorus Ducke"
## [2] "Flora;Angiospermas;Rutaceae A.Juss.;Andreadoxa Kallunki;Andreadoxa flava Kallunki"
## [3] "Flora;Angiospermas;Rutaceae A.Juss.;Angostura Roem. & Schult.;Angostura bracteata (Nees & Mart.) Kallunki"
## [4] "Flora;Angiospermas;Rutaceae A.Juss.;Angostura Roem. & Schult.;Angostura longiflora (K.Krause) Kallunki"
## [5] "Flora;Angiospermas;Rutaceae A.Juss.;Angostura Roem. & Schult.;Angostura quinquefolia Kallunki"
## [6] "Flora;Angiospermas;Rutaceae A.Juss.;Angostura Roem. & Schult.;Angostura simplex Kallunki"
Eu quero extrair apenas a informação referente ao segundo grupo taxonômico mais inclusivo no qual cada espécie pertence, o segundo elemento entre os separadores:
# função para extrair determinado elemento de determinada string com determinado separador
function_split_pluck <- function(string,split=";",pluck=2){
string %>%
strsplit(split = split) %>%
unlist() %>%
pluck(pluck)
}
# aplico a função na coluna e crio uma nova coluna apenas com o grande grupo taxonomico
df_master['major_group'] <- map_chr(df_master$higherClassification, function_split_pluck)
df_master <- df_master %>% select(-higherClassification) # removo a coluna obsoleta
A maior parte dos dados já está pronta, mas a tabela ainda precisa de uns ajustes finais. Por exemplo, seria melhor remover acentos de algumas colunas do df_master
, dado que eles podem ser problemáticos para algumas visualizações:
df_master <- df_master %>%
# vou selecionar apenas as colunas que quero formatar
mutate_at(c("lifeForm","endemism","vernacular_name","major_group"),
iconv,
from="UTF-8",to="ASCII//TRANSLIT") # iconv remove os acentos dessas colunas
Também vou reordenar e renomear as colunas de maneira mais intuitiva:
df_master <- df_master %>%
select(id,major_group,
family,scientificName,
desc_year,descriptor,
lifeForm,vegetationType,
endemism,phytogeographicDomain,
states,vernacular_name) %>%
rename(scientific_name=scientificName,
phytogeographic_domains=phytogeographicDomain,
life_form=lifeForm,
vegetation_type=vegetationType)
Agora vale uma reolhada na estrutura do data frame para checar os tipos das variáveis:
glimpse(df_master)
## Rows: 38,079
## Columns: 12
## $ id <dbl> 264, 280, 285, 301, 315, 319, 342, 343, 439, …
## $ major_group <chr> "Angiospermas", "Angiospermas", "Angiospermas…
## $ family <chr> "Rutaceae", "Rutaceae", "Rutaceae", "Rutaceae…
## $ scientific_name <chr> "Adiscanthus fusciflorus Ducke", "Andreadoxa …
## $ desc_year <dbl> 1922, 1998, 1998, 1998, 1998, 1998, 1998, 189…
## $ descriptor <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "…
## $ life_form <chr> "Arvore", "Arvore", "Arvore", "Arvore", "Arvo…
## $ vegetation_type <chr> "Campinarana;Floresta Ombrófila (= Floresta P…
## $ endemism <chr> "Nao endemica", "Endemica", "Endemica", "Nao …
## $ phytogeographic_domains <chr> "Amazônia", "Mata Atlântica", "Mata Atlântica…
## $ states <chr> "PA;AM;AC", "BA", "RJ;ES;BA", "AC;MT", "MA;PA…
## $ vernacular_name <chr> NA, NA, "gramirim-cafe", "matapira;mata rabuj…
A maior parte das colunas está formatada como string, embora a maioria seja constituída de variáveis categóricas, vou converter algumas que não contém separadores e que não são números para fatores:
glimpse(
df_master <- df_master %>% mutate_at(c("life_form",
"endemism",
"scientific_name",
"family"), as.factor)
)
## Rows: 38,079
## Columns: 12
## $ id <dbl> 264, 280, 285, 301, 315, 319, 342, 343, 439, …
## $ major_group <chr> "Angiospermas", "Angiospermas", "Angiospermas…
## $ family <fct> Rutaceae, Rutaceae, Rutaceae, Rutaceae, Rutac…
## $ scientific_name <fct> Adiscanthus fusciflorus Ducke, Andreadoxa fla…
## $ desc_year <dbl> 1922, 1998, 1998, 1998, 1998, 1998, 1998, 189…
## $ descriptor <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "…
## $ life_form <fct> Arvore, Arvore, Arvore, Arvore, Arvore, Arvor…
## $ vegetation_type <chr> "Campinarana;Floresta Ombrófila (= Floresta P…
## $ endemism <fct> Nao endemica, Endemica, Endemica, Nao endemic…
## $ phytogeographic_domains <chr> "Amazônia", "Mata Atlântica", "Mata Atlântica…
## $ states <chr> "PA;AM;AC", "BA", "RJ;ES;BA", "AC;MT", "MA;PA…
## $ vernacular_name <chr> NA, NA, "gramirim-cafe", "matapira;mata rabuj…
As variáveis que quero investigar podem ser divididas em 4 grupos:
Com todas já compiladas no df_master
, posso começar a mexer nos dados.
Das 38079 espécies presentes no df_master
, 23.415 possuem a informação referente ao ano de descrição. Isso corresponde a cerca de 61.4905854% da amostra. Ainda assim, um dado interessante de se visualizar:
p1 <- df_master %>%
count(desc_year) %>%
mutate(desc_century = case_when(desc_year < 1800 ~ "Século 18",
desc_year >= 1800 & desc_year < 1900 ~ "Século 19",
desc_year >= 1900 & desc_year < 2000 ~ "Século 20",
desc_year > 2000 ~ "Século 21")) %>% na.omit() %>%
ggplot(aes(x=desc_year,y=n,color=desc_century)) +
geom_line(aes(group=1)) + coord_cartesian(ylim = c(0,900), xlim = c(1750,2020)) +
theme_bw() +
removeGridX() +
theme(panel.border = element_blank()) + geom_smooth(aes(group=1),alpha=0.1, linetype = 'dashed', size = 0.5, color = 'black') +
geom_text(aes(x = 1920, y = 750, label = "855 espécies \ndescritas em 2001"),
hjust = 0,
vjust = 0.5,
lineheight = 0.8,
colour = "#555555",
label.size = NA,
size = 4) +
geom_curve(aes(x = 2001, y = 855, xend = 1980, yend = 800),
colour = "#555555",
size=0.5,
curvature = 0.2,
arrow = arrow(length = unit(0.03, "npc"))) +
scale_color_manual(values = c("#1380A1","#990000", "#FAAB18","#588300")) +
scale_x_continuous(limits=c(1750,2020), breaks = seq(1750,2020,50)) + xlab('') +
theme(legend.title = element_blank()) + ggtitle('Número de descrições anuais de espécies no Brasil de 1750 a 2020') +
ylab("Total de espécies") + xlab("Ano") +
scale_y_continuous(limits = c(0,800),breaks=seq(0,800,150)) +
geom_curve(aes(x = 1990, y = 750, xend = 2005, yend = 750),
colour = "#555555",
size=0.5,
curvature = 0.2,
arrow = arrow(length = unit(0.03, "npc")))
p1
A curva indica um aumento na taxa de descrições ao longo do século 18, seguida por leve diminuição na taxa em meados do século 19, que finalmente, assume uma taxa de crescimento constante a partir daí, com o ano com maior número de descrições sendo 2001.
Também é interessante ver a diferença das taxas e números absolutos por século:
p2 <- df_master %>%
count(desc_year) %>%
mutate(desc_century = case_when(desc_year < 1800 ~ "Século 18",
desc_year >= 1800 & desc_year < 1900 ~ "Século 19",
desc_year >= 1900 & desc_year < 2000 ~ "Século 20",
desc_year > 2000 ~ "Século 21")) %>% na.omit() %>%
ggplot(aes(x=desc_century,y=n,fill=desc_century)) + geom_boxplot() +
scale_fill_manual(values = c("#1380A1","#990000", "#FAAB18","#588300")) +
theme_bw() +
removeGridX() +
theme(panel.border = element_blank(), legend.position = "none",
plot.title = element_text(size=10)) + xlab("") + ylab("") +
scale_y_continuous(limits = c(0,800),breaks=seq(0,800,150)) + ggtitle("Distribuição do número de descrições anuais,\npor século.")
p3 <- df_master %>%
count(desc_year) %>%
mutate(desc_century = case_when(desc_year < 1800 ~ "Século 18",
desc_year >= 1800 & desc_year < 1900 ~ "Século 19",
desc_year >= 1900 & desc_year < 2000 ~ "Século 20",
desc_year > 2000 ~ "Século 21")) %>% na.omit() %>%
group_by(desc_century) %>% summarise(total=sum(n)) %>%
ggplot(aes(x=desc_century,y=total, fill = desc_century)) + geom_bar(stat='identity') +
scale_fill_manual(values = c("#1380A1","#990000", "#FAAB18","#588300")) +
theme_bw() +
removeGridX() +
theme(panel.border = element_blank(), legend.position = "none",
plot.title = element_text(size=10)) + xlab("") + ylab("") +
ggtitle("Total de descrições por século.")
(grid_p <- plot_grid(p2,p3, nrow=1,ncol = 2,labels = c('A', 'B')))
Os boxplots do número de espécies descritas anualmente por século (A) indica um relativo baixo número de descrições no século 18, algo esperado pela recém criação do sistema lineniano. Por outro lado, eles também deixam clara a alta taxa de descrições do século 21, que tem uma mediana de aproximadamente 300 espécies descritas por ano. Os gráficos de barras (B) indicam que, embora apenas 20% do século 21 tenha passado, ele já tem cerca de 80% do total de descrições do século 20.
Usando a coluna desc_author
do df_master
, é possível ver qual foi o autor mais prolífico de 2001 (ano com maior número de descrições):
head(df_master %>%
filter(desc_year == 2001) %>%
{table(.$descriptor)} %>%
as.data.frame() %>%
arrange(desc(Freq))) %>%
rename(author=Var1,species_descriptions=Freq)
O fato de o termo Orgs. aparecer no autor com maior número de descrições de 2001, indica se tratar de uma obra. Ainda, o número de espécies descritas associadas com esse nome é muito maior que a média dos demais autores, o que faz sentido, dado que a obra deve compilar descrições de vários autores. Uma busca rápida me mostrou que um livro entitulado “Biodiversidade de algas de ambientes continentais do Estado do Rio de Janeiro”, com as referidas autoras, foi publicado em 2001. Partindo do título, podemos pressupor que uma grande quantidade de algas foram descritas nesse ano. Normalmente espera-se que o número absoluto de angiospermas descritas por ano seja maior que os demais grandes grupos, isso fica evidente quando os dados são agrupados por século e grupo taxonômico:
df_master %>%
mutate(desc_century = case_when(desc_year < 1800 ~ "Século 18",
desc_year >= 1800 & desc_year < 1900 ~ "Século 19",
desc_year >= 1900 & desc_year < 2000 ~ "Século 20",
desc_year > 2000 ~ "Século 21")) %>% group_by(desc_century) %>%
count(major_group) %>% na.omit() %>%
ggplot(aes(x=desc_century,y=n, fill = major_group)) + geom_bar(stat='identity', position = 'dodge') +
ggtitle("Total de espécies descritas (log), por século, agrupado por grupo taxonômico.") +
scale_fill_manual(values = c("#1380A1",'#177506', "#FAAB18","#f55d42",'#940d8f')) +
scale_y_log10() + xlab("") + ylab("") +
theme_bw() +
removeGridX() + labs(fill = "Grupo taxonômico") +
theme(panel.border = element_blank(),plot.title = element_text(size=10))
A escala do gráfico foi convertida para log, dado que a diferença do número de descrições de gimnospermas (relativamente baixo) acaba mascarando a presença delas. Gimnospermas aparecem descritas apenas no século 19 e 21, sendo a maioria no primeiro. Angiospermas correspondem ao grupo com maior número de descrições em todos séculos, embora a diferença entre estas e as algas seja bem menor no século 21.
Olhando por outra ótica, usando um gráfico de violino, é possível reparar essas particularidades ainda melhor:
df_master %>% ggplot(aes(y=as.numeric(desc_year),x=major_group,fill=major_group)) +
xlab("Major group") +
ylab("Description year") +
geom_violin(color = "black") +
geom_curve(aes(y = 1980, yend = 1999, x = 1.70, xend=1.5),
colour = "black",
size=0.5,
curvature = 0.2,
arrow = arrow(length = unit(0.03, "npc"))) +
scale_fill_manual(values=c("#1380A1",'#177506', "#FAAB18","#f55d42",'#940d8f')) +
theme_bw() +
theme(plot.title = element_text(hjust=0.5),
legend.position = "none") +
removeGridX() +
geom_text(aes(x = 1.7, y = 1963, label = "Pico \nem 2001"),
colour = "black",
label.size = NA,
size = 4)+
ylab("Grupo taxonômico") + xlab("Ano de descrição") +
theme(panel.border = element_blank()) +
geom_curve(aes(y = 1800, yend = 1850, x = 4.54, xend=4.1),
colour = "black",
size=0.5,
curvature = 0.2,
arrow = arrow(length = unit(0.03, "npc"))) +
scale_fill_manual(values=c("#1380A1",'#177506', "#FAAB18","#f55d42",'#940d8f')) +
theme_bw() +
theme(plot.title = element_text(hjust=0.5),
legend.position = "none") +
removeGridX() +
ggtitle("Distribuição do número de descrições anuais, agrupadas por grupo taxonômico") +
geom_text(aes(x = 4.5, y = 1778, label = "Alta densidade\nno século 19"),
colour = "black",
label.size = NA,
size = 4)+
xlab("Grupo taxonômico") + ylab("Ano de descrição") +
theme(panel.border = element_blank(),plot.title = element_text(size=10))
Nele fica clara a maior densidade de descrições de gimnospermas no século 19, característica exclusiva ao grupo. O gráfico também reforça a importância da obra de 2001 no histórico de descrições das algas. Inclusive, embora na maior parte dos anos o grupo com maior número de descrições seja o das angiospermas, em 2001 esse não foi o caso:
df_master %>% filter(desc_year==2001) %>%
count(major_group) %>% na.omit() %>%
ggplot(aes(x=major_group,y=n, fill = major_group)) + geom_bar(stat='identity', position = 'dodge') +
scale_fill_manual(values = c("#1380A1",'#177506', "#FAAB18","#f55d42",'#940d8f')) +
ggtitle("Total de espécies descritas em 2001, por grupo taxonômico.") + xlab("") +
ylab("") +
theme_bw() +
removeGridX() +
theme(panel.border = element_blank(), legend.position = "none")
Em 2001 o total de algas descritas foi quase o triplo do de angiospermas. Além dessa questão, dado que a obra trata do estado do Rio de Janeiro, espera-se que isso seja refletido no total de espécies descritas para o estado neste ano. Isso pode ser visualizado em um heatmap, primeiro englobando todo intervalo de tempo de descrições da amostra:
df_master$desc_year <- as.character(df_master$desc_year)
df_temp <- df_stack_parse(df_master,column1 = "desc_year",column2 = "states",slice_value = 3,parse1 = FALSE)
x <- df_temp[[1]] # selecionando o input que preciso da funcao que escrevi
x <- x %>% filter(y != "NA") # remover NA
x$x <- as.numeric(x$x) # converter o ano para numerico
x$y <- as.factor(x$y)
# pequeno macete para conseguir colocar os estados dos dois lados do plot
x <- x %>% filter(!is.na(y))
labs2 <- levels(x$y)
labs2 <- c("ES", "MG", "RJ","SP",
"PR","RS","SC",
"DF","MS","MT","GO",
"SE","RN","PI","PE","PB","MA","CE",
"BA","AL","TO","RR","RO","PA","AM","AP","AC")
# agora construo o heatmap
x %>%
mutate(y = fct_relevel(y,
"ES", "MG", "RJ","SP",
"PR","RS","SC",
"DF","MS","MT","GO",
"SE","RN","PI","PE","PB","MA","CE",
"BA","AL","TO","RR","RO","PA","AM","AP","AC")) %>%
ggplot(aes(x, as.numeric(y), fill= value)) + # nomes de estado como numericos
geom_tile(colour = "black") +
scale_fill_gradientn(colours = pal, name = "Total de espécies", na.value = "black") +
xlab("Year") + ylab("State") +
theme_bw() +
theme(axis.text.x = element_text(angle = 90),
plot.title = element_text(hjust=0.5,face="bold"),
panel.background = element_rect(fill="black", colour="black"),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank()) +
scale_x_continuous(breaks = seq(1750,2020,10),
expand = c(0,0)) + # tirando o panning
scale_y_continuous(breaks = 1:length(labs2),
labels = labs2, # mascarando os fatores com nomes
sec.axis = sec_axis(~., # eixo secundario para ter estados dos dois lados
breaks = 1:length(labs2),
labels = labs2),expand = c(0,0)) +
xlab("Ano") + ylab("Estado") + ggtitle("Descrição de espécies/ano/estado no Brasil de 1750 a 2020.")
Este gráfico representa o número de espécies descritas por ano, por estado da federação. Os estados foram propositadamente ordenados por região, para expor o fato de que os estados do sudeste são, em geral, mais bem amostrados que os demais, especialmente quando se trata de anos recentes. Este já é um fato conhecido, por estas regiões receberem mais recursos para a pesquisa. Ainda assim vale observar a quantidade expressiva de espécies descritas para os estados da Bahia, Pará e Amazonas. A mancha vermelha no gráfico representa o estado do Rio de Janeiro, no ano de 2001. Restringindo o gráfico para décadas mais recentes este fato fica mais claro:
x %>%
mutate(y = fct_relevel(y,
"ES", "MG", "RJ","SP",
"PR","RS","SC",
"DF","MS","MT","GO",
"SE","RN","PI","PE","PB","MA","CE",
"BA","AL","TO","RR","RO","PA","AM","AP","AC")) %>%
ggplot(aes(x, as.numeric(y), fill= value)) +
geom_tile(colour = "black") +
scale_fill_gradientn(colours = pal,
name = "Total de espécies",
na.value = "black") +
xlab("Year") + ylab("State") +
theme_bw() +
geom_vline(xintercept=2000, linetype = "dashed",size = 0.5) +
geom_vline(xintercept=2010, linetype = "dashed",size = 0.5) +
theme(axis.text.x = element_text(angle = 90),
plot.title = element_text(hjust=0.5,face="bold")) +
coord_cartesian(xlim = c(1990,2019)) + # limitando anos que aparecem no plot
scale_x_continuous(breaks = seq(1990,2019,1), expand = c(0,0)) +
scale_y_continuous(breaks = 1:length(labs2),
labels = labs2,
sec.axis = sec_axis(~.,
breaks = 1:length(labs2),
labels = labs2),expand = c(0,0)) +
xlab("Ano") + ylab("Estado") + ggtitle("Descrição de espécies/ano/estado no Brasil de 1990 a 2020.")
Além dos fatos já expostos e reforçados, é possível ver que a década entre 2000 e 2010 foi a mais prolífica até então na quantidade de espécies nativas descritas. Ainda, esse número parece cair expressivamente a partir de 2013.
Poderíamos esperar que, além da questão do financiamento, estados maiores possuem maior quantidade de espécies descritas, mas este definitivamente não é o caso, uma vez que o Rio de Janeiro, por exemplo, é um dos menores estados brasileiros.
Agregando mais algumas informações isso também pode ser melhor visualizado. Além do número de espécies descritas por ano, vou combinar a extensão territorial dos estados, se eles fazem fronteiras internacionais ou não e a proporção de espécies endêmicas do total de espécies nativas descritas em cada um. Plotando todos esses dados em um único gráfico, posso tentar visualizar algumas coisas:
# vetor com iniciais de cada estado
states <- c("TO","SE","SP","SC","RR","RO","RS","RN","RJ","PI","PE","PR","PB","PA","MG","MS","MT","MA","GO","ES","DF","CE","BA","AM","AP","AL","AC")
# vetor com presenca/ausencia de fronteiras internacionais
border <- c("Não","Não","Não","Sim","Sim","Sim","Sim","Não","Não","Não","Não", "Sim","Não","Sim","Não","Sim","Sim","Não","Não","Não","Não","Não","Não", "Sim","Sim","Não","Sim")
#area de cada estado em km2
area <- c(277720,21915,248222,95736,224300,237590,281730,52811,43780,251577,98311,199307,56585,1247954,586522,357145,903366,331937,340111,46095,5779,148920,564733,1559159,142828,27778,164123)
# combinando tudo em um df
df_states <- tibble(state=states,area=area,border=border)
# endemicas e nao endemicas por estado
# coluna de endemismo NAO precisa de parsing
df_state_endemism <- df_stack_parse(df_master,
column1 = "endemism",
column2 = "states",
parse1 = FALSE)[[1]]
# total de especies por estado
a <- df_state_endemism %>%
group_by(y) %>%
summarise(species=sum(value))
# total de endemicas por estado
b <- df_state_endemism %>% filter(x=="Endemica") %>% group_by(y) %>% summarise(endemics=sum(value))
# junto os dois e calculo as props
c <- left_join(a,b,by = "y") %>%
mutate(prop= endemics*100/species) %>%
rename(state=y)
k <- left_join(c,df_states,by="state")
# pequena abordagem para marcar o que quero no plot
k[['temp']] <- ""
labels <- c(13,3,11,15,5,20,27,8,9,14,19,26)
k[['temp']][labels] <- k$state[labels]
# primeiro o scatter
p1 <- k %>% filter(state != "NA") %>% ggplot(aes(x=species,y=prop,size=area,label=state,color=border)) +
geom_point() +
geom_smooth(aes(group=1),alpha=0.1, linetype = 'dashed', size = 0.5, color = 'black',method="lm") +
scale_color_manual(values=c(pal[1],pal[5]), name = "miau") +
geom_hline(yintercept=20, linetype = "dashed",size = 0.1) +
geom_hline(yintercept=40, linetype = "dashed",size = 0.1) +
ylab("Proporção de endêmcias (%)") + xlab("Total de espécies") +
theme_bw() +
geom_label_repel(aes(label = temp),
box.padding = 0.35,
point.padding = 0.5,
segment.color = 'grey50') +
scale_size(guide = "none") +
theme(legend.position = "none",panel.border = element_blank())
# agora o boxplot
p2 <- k %>% na.omit() %>% ggplot(aes(y=prop,fill=border,x=border)) +
geom_boxplot() +
theme_bw() +
scale_fill_manual(values = c(pal[1],pal[5])) +
ylab("Proporção de endêmicas (%)") +
xlab("") +
theme(axis.text.x = element_blank(),legend.position = "left",panel.border = element_blank()) +
labs(fill = " Limites \n internacionais")
# combinando tudo em um grid
p3 <- plot_grid(p1,p2, ncol = 2, labels = c("A","B"))
# adicionando um titulo
title <- ggdraw() +
draw_label(
"Relação entre as proporções de espécies endêmicas, total de espécies \ne seus estados de ocorrência (A). Proporção de espécies endêmicas em \nestados com e sem fronteira (B).",
fontface = 'bold',
size=10,
x = 0,
hjust = 0
) +
theme(
plot.margin = margin(0, 0, 0, 7)
)
plot_grid(
title, p3,
ncol = 1,
rel_heights = c(0.1, 1)
)
Esses gráficos contém uma grande quantidade de informação. Primeiramente, o tamanho dos estados não parece influenciar na quantidade de espécies descritas. Os maiores estados brasileiros (Amazonas, Pará e Mato grosso, marcados no gráfico), contém uma quantidade de espécies descritas menor do que estados como o Rio de Janeiro, São Paulo ou Bahia. Estes, por sua vez, juntamente com o Minas Gerais, também possuem as maiores proporções de espécies endêmicas do total de suas espécies nativas. Como o esperado, estados fronteiriços possuem proporção menor de endêmicas: todos aqueles mais de 40% de sua flora sendo endêmica não fazem fronteiras internacionais. A lógica contrária também se aplica, dado que todos estados com menos de 20% de sua flora sendo endêmcia possuem fronteiras internacionais.
Vale notar, ainda, que os quatro estados com maiores valores de riqueza de espécies e proporção de endêmicas abrigam principalmente os domínios da Mata Atlântica e do Cerrado, dois conhecidos hotspots da biodiversidade, com altas taxas de diversidade em senso amplo. Estes domínios, juntamente com a Caatinga, possuem as maiores proporções de endemismo do país:
df_temp <- df_stack_parse(df_master,column1 = "endemism",
column2 = "phytogeographic_domains",
parse1 = FALSE, slice_value = 3)
df_temp[[1]] %>%
mutate(y = fct_relevel(y,
"Mata Atlântica", "Cerrado", "Caatinga",
"Amazônia", "Pampa", "Pantanal")) %>%
ggplot(aes(fill=x, y=value, x=y)) +
ylab("Proportion") +
xlab("Phytogeographic domain") +
geom_bar(position="fill", stat="identity", color = "black") +
theme_bw() + xlab("") + ylab("") +
scale_fill_manual(name = "Endemismo",values=c(pal[5],pal[1]), aesthetics = "fill",labels=c("Endêmicas","Não endêmicas")) +
removeGridX() +
theme(panel.border = element_blank()) + ggtitle("Proporção de espécies endêmicas por domínio fitogeográfico.")
Mudando drasticamente a análise de direção, ainda existem mais algumas variáveis a serem checadas. Vou explorar um pouco agora os dados de formas de vida e tipos de vegetação de ocorrência das espécies. Primeiro uma olhada nas formas de vida mais frequentes da flora brasileira:
df_life_forms <- as_tibble(as.data.frame(table(unlist(strsplit(as.character(df_master$life_form),split=";")))))
p1 <- df_life_forms %>%
mutate(Var1=fct_reorder(Var1,desc(Freq))) %>%
ggplot(aes(fill=Var1,y=Freq,x=Var1)) +
geom_col(position = "dodge",fill=pal[1], color = "black") +
xlab("") +
ylab("") +
theme_bw() +
theme(axis.text.x = element_text(angle = 90,size = 10),panel.border = element_blank(),
plot.title = element_text(size=10)) +
removeGridX() + ggtitle("Total de espécies em cada forma de vida")
p2 <- df_master %>%
count(major_group) %>% na.omit() %>% mutate(major_group=as.factor(major_group)) %>%
mutate(major_group=fct_reorder(major_group,desc(n))) %>%
ggplot(aes(x=major_group,y=n, fill = major_group)) + geom_bar(stat='identity', position = 'dodge') +
scale_fill_manual(values = c('#177506', "#1380A1", "#FAAB18", '#940d8f', "#f55d42")) +
theme_bw() +
xlab("") +
ylab("") +
theme(axis.text.x = element_text(angle = 90,size = 10),
legend.position = "none",plot.title = element_text(size=10)) +
removeGridX() +
theme(panel.border = element_blank(),
legend.position = "none") +
ggtitle("Total de espécies em cada grupo taxonômico")
(p3 <- plot_grid(p1,p2, ncol = 2))
Não inesperadamente, as formas de vida mais frequentes são aquelas associadas com angiospermas, seguidas de formas de vida associadas à algas e depois briófitas. Após as dez formas de vida mais frequentes (que seguem a ordem descrescente supracitada), vemos formas de vida variadas, sem ordem taxonomica. Vale ressaltar que algumas das formas de vida associadas à angiospermas são compartilhadas por samambaias, licófitas e gimnospermas, o que influencia nesse resultado, ainda que sejam grupos com quantidade menor de espécies descritas (gimnospermas parecem sequer existir no gráfico, devido ao fato do número ser muito pequeno).
Formas de vida são frequentemente associadas com os ambientes em que as espécies ocorrem. Não seria, a princípio, esperado que formas de vida ligadas a briófitas ocorressem em alta frequência em uma vegetação de clima quente e seco. Como ambos esses dados estão disponíveis, visualizando-os em conjunto podem potencialmente revelar alguns padrões interessantes. Para isso vou plotar os tipos de vegetação mais frequentemete associados a cada forma de vida, no formato de um gráfico de barras empilhado:
# limpando os simbolos
df_master$vegetation_type <- gsub("\\(","",df_master$vegetation_type)
df_master$vegetation_type <- gsub("\\)","",df_master$vegetation_type)
df_master$vegetation_type <- gsub("=","",df_master$vegetation_type)
df_master$life_form <- as.character(df_master$life_form)
# aplicando a funcao
# setando o slice para 3
df_temp <- df_stack_parse(df_master,column1 = "life_form",column2 = "vegetation_type",slice_value = 3)
df_temp[[2]] %>% # selecionando o df com os top 3 de cada caso
ggplot(aes(fill=y, y=value, x=x)) +
ylab("") +
xlab("") +
geom_bar(position="fill", stat="identity", color = "black") +
scale_fill_brewer(palette = "Paired") +
theme_bw() +
labs(fill='Tipo de vegetação') +
theme(axis.text.x = element_text(angle = 90,size = 20),
axis.text.y = element_text(size = 20),
axis.title = element_text(size = 20),
legend.text=element_text(size=20),
legend.title = element_text(size=20),
plot.title = element_text(size=20),
panel.border = element_blank()) +
removeGridX() + ggtitle("Três tipos de vegetação mais frequentes, agrupados por forma de vida.")
Nesse gráfico estão representadas os três tipos de vegetação mais frequentes para cada forma de vida de maneira proporcional. Não existem tipos de vegetação associados à algas, por isso a ausência dessa informação no gráfico. Fica logo evidente a frequência em que domina a floresta ombrófila (laranja), dentre as demais formas de vida. Quase todas formas de vida tem essa vegetação dominando dentre as mais frequentes, o que é minimamente esperado dado que uma grande quantidade de espécies nativas ocorre em Mata Atlântica, domínio à qual este tipo de vegetação está mais associado. Outro fato interessante evidenciado por esse gráfico é a importância das vegetações sobre afloramentos rochosos (roxo) para espécies suculentas: apenas nestas, este tipo de vegetação figura entre os mais frequentes. É também curioso que a Floresta Ombrófila Mista (lilás) esteja aparecendo nesse gráfico, dado que trata-se de um tipo de vegetação bastante devastado e restrito a regiões específicas do sul do Brasil. Ainda, todas as formas de vida que possuem essa vegetação figurando como frequente estão associadas a briófitas, algo que merece uma investigação futura.
Por último, vou analisar rapidamente alguns dados a respeito dos nomes populares disponíveis para as espécies. Quero responder duas perguntas simples:
Esses dados tem que ser limpos novamente para que a análise fique menos enviesada, dado que estes são um pouco mais sensíveis de se trabalhar. Alguns nomes aparecem capitalizados, outros não, além disso alguns símbolos não alfanuméricos podem atrapalhar a contagem. Esse é um assunto por si só, mas farei uma pequena limpeza aqui nos nomes para melhorar o resultado e fragmentar os nomes (lembrando que cada nome vernacular de determinada espécie é separado por “;”, como no casos dos estados da federação):
# removendo os hifens
df_master$vernacular_name <- tolower(gsub("-"," ",df_master$vernacular_name))
# substituindo as virgulas por pontos e virgulas
# isso deixa todos separadores iguais
# alguns nomes estavam separados por virgulas
df_master$vernacular_name <- tolower(gsub(",",";",df_master$vernacular_name))
# lista dos nomes mais frequentes
{table(na.omit(unlist(strsplit(df_master$vernacular_name,split=";"))))} %>% # vetor com todos nomes populares da amostra
{as_tibble(as.data.frame(.))} %>% arrange(desc(Freq)) %>% # contagem de frequencias, output como data frame
head() # seis nomes mais frequentes
O nome popular “Taquara” é o mais frequente nessa amostra, relacionado comumente com uma variedade de bambus (família Poaceae), conhecidas por terem uso amplo, desde para a construção em geral como para a criação de instrumentos musicais. Nesse caso, todas espécies associadas com esse nome parecem pertencer à mesma família:
as.character(unique(df_master$family[grep("taquara",df_master$vernacular_name,ignore.case = T)]))
## [1] "Poaceae"
O segundo colocado em nossa lista já não segue esse padrão:
table(as.character(df_master$family[grep("envira",df_master$vernacular_name,ignore.case = T)]))
##
## Annonaceae Fabaceae Lecythidaceae Malvaceae Salicaceae
## 80 1 1 3 1
## Thymelaeaceae Ulmaceae
## 1 2
Embora a esmagadora maioria das espécies com o nome “Envira” associado pertençam à familia Annonaceae, ele também aparece associado a espécies de outras famílias. Embora não seja um resultado surpreendente, continua sendo um fato interessante.