Script utilizado na aula 2 para demostrar as funções do pacote dpyr e tidyr do tidyverse
Instalando os pacotes
Nessa aula vamos utilizar o mesmo conjunto de dados da aula 1 para demostrar as funções dos pacotes tidyr e dplyr do tidyverse. O primeiro passo então é carregar o pacote. Confiram a versão e atualizem para versão 2.0.0 usando a função tidyverse_update()!
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.1.4 ✔ readr 2.1.5
✔ forcats 1.0.0 ✔ stringr 1.5.1
✔ ggplot2 3.5.1 ✔ tibble 3.2.1
✔ lubridate 1.9.3 ✔ tidyr 1.3.1
✔ purrr 1.0.2
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
# tidyverse_update()
Carregando o conjunto de dados
Agora vamos determinar o diretório de trabalho e carregar os dados, conforme aprendemos na aula anterior.
Você deve colocar o diretório de acordo com o seu caminho no computador, e de acordo com a localização dos seus dados.
# setwd("C:/Marina/Pos-doutorado/PNPD_UFPR/Vis Man Dados/Aula 2")# dados <- read.csv("Dados.csv")dados<-readr::read_csv('https://raw.githubusercontent.com/scalonmc/VisMan/master/VisManDados/Aula1/dados.csv')
Rows: 129 Columns: 13
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (3): Tratamento, especie, Grupo
dbl (10): Amostra, individuo, N, P, Mg, K, Ca, Al_ppm, area, peso
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# A tibble: 6 × 13
N P Amostra Tratamento especie Grupo individuo Mg K Ca
<dbl> <dbl> <dbl> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
1 2.36 0.114 1 Floresta AT D 1 0.150 1.20 0.319
2 2.07 0.114 2 Floresta AT D 2 0.180 1.44 0.413
3 2.03 0.121 3 Floresta AT D 3 0.133 0.366 0.371
4 1.32 0.0643 4 Floresta BC B 1 0.159 0.679 0.576
5 1.23 0.0714 5 Floresta BC B 2 0.113 0.957 0.458
6 1.37 0.0786 6 Floresta BC B 3 0.116 0.75 0.347
# ℹ 3 more variables: Al_ppm <dbl>, area <dbl>, peso <dbl>
Rbase
Para fazer a mesma coisa no Rbase
São comandos bem simples que eu acho importante demostrar
O diferencial é precisar verificar o número correspondente da coluna do dataframe
A função arrange() permite colocarmos os dados em determinada ordem. Isso é importante principalmente para verificar tendências ou outliers Aqui vamos colocar os dados na ordem do maior valor de Al par ao menor para verificarmos as plantas acumuladoras de alumínio. Vamos usar a função head() para olhar como os dados foram ordenados do maior valor de Al.
# A tibble: 6 × 11
Vegetation Species `Phenological group` N P Mg K Ca Al
<chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Savana BC B 1.56 0.0714 0.222 0.879 0.968 258.
2 Savana SA B 2.08 0.0714 0.0941 0.561 0.221 258.
3 Savana SA B 1.91 0.0643 0.0734 0.313 0.113 252.
4 Savana BC B 1.41 0.0786 0.171 0.814 0.603 239.
5 Savana SA B 1.99 0.0571 0.0704 0.369 0.15 239.
6 Campo CB B 1.56 0.0786 0.160 0.507 0.503 226
# ℹ 2 more variables: `leaf area` <dbl>, `leaf mass` <dbl>
Mutate
A função mutate() é muito utilizada para diversos objetivos de manipulação. Com ela, podemos:
tibble [129 × 11] (S3: tbl_df/tbl/data.frame)
$ Vegetation : Factor w/ 3 levels "Campo","Floresta",..: 2 2 2 2 2 2 2 2 2 2 ...
$ Species : Factor w/ 15 levels "AT","BC","BS",..: 1 1 1 2 2 2 3 3 3 4 ...
$ Phenological group: Factor w/ 3 levels "B","D","S": 2 2 2 1 1 1 1 1 1 1 ...
$ N : num [1:129] 2.36 2.07 2.03 1.32 1.23 ...
$ P : num [1:129] 0.1143 0.1143 0.1214 0.0643 0.0714 ...
$ Mg : num [1:129] 0.15 0.18 0.133 0.159 0.113 ...
$ K : num [1:129] 1.197 1.444 0.366 0.679 0.957 ...
$ Ca : num [1:129] 0.319 0.413 0.371 0.576 0.458 ...
$ Al : num [1:129] 122.8 251.8 206.5 96.8 103.3 ...
$ leaf area : num [1:129] 288 262 184 149 263 ...
$ leaf mass : num [1:129] 3.63 2.49 2.16 1.86 4.39 ...
new.rename<-mutate(dados.factor, `Phenological group` =recode(`Phenological group`, D ="Deciduous", #2 B ="Semideciduous", S ="Evergreen"), Vegetation =recode(Vegetation, Savana ="Savanna", Floresta ="Forest", Campo ="Grassland"))str(new.rename)
tibble [129 × 11] (S3: tbl_df/tbl/data.frame)
$ Vegetation : Factor w/ 3 levels "Grassland","Forest",..: 2 2 2 2 2 2 2 2 2 2 ...
$ Species : Factor w/ 15 levels "AT","BC","BS",..: 1 1 1 2 2 2 3 3 3 4 ...
$ Phenological group: Factor w/ 3 levels "Semideciduous",..: 2 2 2 1 1 1 1 1 1 1 ...
$ N : num [1:129] 2.36 2.07 2.03 1.32 1.23 ...
$ P : num [1:129] 0.1143 0.1143 0.1214 0.0643 0.0714 ...
$ Mg : num [1:129] 0.15 0.18 0.133 0.159 0.113 ...
$ K : num [1:129] 1.197 1.444 0.366 0.679 0.957 ...
$ Ca : num [1:129] 0.319 0.413 0.371 0.576 0.458 ...
$ Al : num [1:129] 122.8 251.8 206.5 96.8 103.3 ...
$ leaf area : num [1:129] 288 262 184 149 263 ...
$ leaf mass : num [1:129] 3.63 2.49 2.16 1.86 4.39 ...
Função muito útil para transformar variáveis junto com o mutate() de acordo com determinada condição, seguindo a mesma lógica da função equivalente no Rbase ifelse(): ifelse(condição, sim, não)
Note
O diferencial é permitir lidar com valores faltantes!
O símbolo %>% conhecido como pipe é usado para unir as funções, podendo ser mentalmente substituído por “depois” (“then”).
Dessa forma, não precisa se referir aos dados que estão sendo utilizados no início de cada função pois o pipe já assume que o produto de uma etapa é o impute da seguinte.
Assim, organizar o seu código aplicando todos os comandos que fizemos acima, mas usando pipe reduz o número de linhas e deixa tudo mais limpo.
Veja as etapas para chegar no dataset final:
final.pipe<-dados%>%mutate_if(is.character, as.factor)%>%#mudar classe dos objetosselect(-Amostra, -individuo)%>%# eliminar colunas inuteisrename(Vegetation =Tratamento, Species =especie, `Phenological group` =Grupo, Al =Al_ppm, `leaf area` =area, `leaf mass` =peso)%>%#renomear variáveismutate(`Phenological group` =recode(`Phenological group`, D ="Deciduous", B ="Semideciduous", S ="Evergreen"), Vegetation =recode(Vegetation, Savana ="Savanna", Floresta ="Forest", Campo ="Grassland"))%>%# renomear os fatoresmutate(SLA=(`leaf area`/`leaf mass`), `N:P` =N/P)#criar novas variáveis summary(final.pipe)
Vegetation Species Phenological group N
Grassland:39 AT : 9 Semideciduous:44 Min. :0.612
Forest :45 BC : 9 Deciduous :45 1st Qu.:1.225
Savanna :45 CB : 9 Evergreen :40 Median :1.413
DM : 9 Mean :1.704
GN : 9 3rd Qu.:2.026
KC : 9 Max. :4.994
(Other):75
P Mg K Ca
Min. :0.03570 Min. :0.0053 Min. :0.1910 Min. :0.0725
1st Qu.:0.06430 1st Qu.:0.0745 1st Qu.:0.3760 1st Qu.:0.1738
Median :0.07140 Median :0.1026 Median :0.5090 Median :0.2727
Mean :0.08012 Mean :0.1124 Mean :0.6624 Mean :0.3319
3rd Qu.:0.08570 3rd Qu.:0.1471 3rd Qu.:0.8140 3rd Qu.:0.4584
Max. :0.22860 Max. :0.2745 Max. :2.4910 Max. :0.9681
Al leaf area leaf mass SLA
Min. : 19.3 Min. : 34.34 Min. :0.2584 Min. : 31.59
1st Qu.: 116.3 1st Qu.:137.17 1st Qu.:1.8373 1st Qu.: 60.18
Median : 180.8 Median :192.61 Median :2.4810 Median : 77.10
Mean : 1763.2 Mean :204.89 Mean :2.9656 Mean : 78.71
3rd Qu.: 419.5 3rd Qu.:257.68 3rd Qu.:3.8455 3rd Qu.: 94.92
Max. :15012.5 Max. :573.53 Max. :9.4754 Max. :150.00
NA's :3 NA's :3 NA's :3
N:P
Min. : 8.653
1st Qu.:16.781
Median :19.780
Mean :21.896
3rd Qu.:24.412
Max. :63.537
Dica!
Depois que você deixar os seus dados do jeito que você quer, salve novo arquivo de dados manipulados! Da próxima vez que você for usar conjunto da dados você já pode carregar o arquivo modificado e prontinho, sem passar pela etapa de manipulação novamente. Nunca substitua os dados originais! Use a função write.csv() e escreva sempre a extensão (.csv) no arquivo que será salvo.
A função summarise() (ou summarize()) cria um novo dataframe colapsando valores em um sumário. MUITO ÚTIL pra fazer tabelas de médias, desvio padrão, etc. Usualmente utilizamos a função group_by() antes para especificar os grupos. Também pode ser combinada por summarise_all para aplicar a função em todas as variáveis.
# Agrupando e aplicando em todas as colunasmedias2<-final.pipe%>%group_by(Species, Vegetation, `Phenological group`)%>%summarise_all(mean)#médias por colunashead(medias2)
# A tibble: 6 × 13
# Groups: Species, Vegetation [6]
Species Vegetation `Phenological group` N P Mg K Ca Al
<fct> <fct> <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 AT Grassland Deciduous 1.79 0.102 0.165 1.72 0.623 239.
2 AT Forest Deciduous 2.15 0.117 0.154 1.00 0.368 194.
3 AT Savanna Deciduous 2.28 0.129 0.213 1.24 0.736 174.
4 BC Grassland Semideciduous 1.05 0.0476 0.108 0.656 0.404 131.
5 BC Forest Semideciduous 1.30 0.0714 0.130 0.795 0.460 86.0
6 BC Savanna Semideciduous 1.41 0.0690 0.176 0.843 0.708 232.
# ℹ 4 more variables: `leaf area` <dbl>, `leaf mass` <dbl>, SLA <dbl>,
# `N:P` <dbl>
Warning: There was 1 warning in `summarise()`.
ℹ In argument: `across(where(is.numeric), list(media = mean, desvio = sd),
na.rm = T)`.
ℹ In group 1: `Vegetation = Grassland`.
Caused by warning:
! The `...` argument of `across()` is deprecated as of dplyr 1.1.0.
Supply arguments directly to `.fns` through an anonymous function instead.
# Previously
across(a:b, mean, na.rm = TRUE)
# Now
across(a:b, \(x) mean(x, na.rm = TRUE))
Utilizando as funções do tidyr
O tidyr tem apenas 4 funções principais! Vamos entender elas AGORA!
Pivot_longer (antiga funcão gather())
A funçao pivot_longer() empilha os dados. Ela é útil para arranjar os dados de forma que algum conjunto de variáveis torne-se um fator. Alguns tipos de gráficos (como gráficos de barras e boxplots) utilizam essa estrutura. Também pode ser importante para fazer gráficos separados em facetas, sendo que cada faceta seria relacionada a um fator.
Logicamente, TUDO depende da sua pergunta e do que você quer demostrar!!!
Vamos usar pivot_longer() para juntar os nutrientes em uma única coluna.
# A tibble: 6 × 5
# Groups: Species, Vegetation [2]
Species Vegetation `Phenological group` Nutriente media
<fct> <fct> <fct> <chr> <dbl>
1 AT Grassland Deciduous N 1.79
2 AT Grassland Deciduous P 0.102
3 AT Grassland Deciduous Mg 0.165
4 AT Grassland Deciduous K 1.72
5 AT Grassland Deciduous Ca 0.623
6 AT Forest Deciduous N 2.15
# A tibble: 6 × 6
# Groups: Species [2]
Species `Phenological group` Nutriente Grassland Forest Savanna
<fct> <fct> <chr> <dbl> <dbl> <dbl>
1 AT Deciduous N 1.79 2.15 2.28
2 AT Deciduous P 0.102 0.117 0.129
3 AT Deciduous Mg 0.165 0.154 0.213
4 AT Deciduous K 1.72 1.00 1.24
5 AT Deciduous Ca 0.623 0.368 0.736
6 BC Semideciduous N 1.05 1.30 1.41
Unite
A função unite junta, como o próprio nome diz, duas ou mais colunas em uma só. Vamos juntar os fatores para criar uma variável de interação com grupo e tratamento, especificando um separador, no caso _ .
A própria documentação dos pacotes é bem completa! tidyr ou dplyr
FIM
Source Code
---title: "Semana 2 - Manipulação de Dados"subtitle: "Aula Prática"author: "Marina Scalon"date: "07 Oct 2024"title-block-banner: trueformat: html: code-link: true code-tools: true theme: minty toc: true---Script utilizado na aula 2 para demostrar as funções do pacote `dpyr` e `tidyr` do `tidyverse`## Instalando os pacotesNessa aula vamos utilizar o mesmo conjunto de dados da aula 1 para demostrar as funções dos pacotes tidyr e dplyr do tidyverse. O primeiro passo então é carregar o pacote. Confiram a versão e atualizem para versão 2.0.0 usando a função *tidyverse_update()*!```{r}library(tidyverse)# tidyverse_update()```## Carregando o conjunto de dadosAgora vamos determinar o diretório de trabalho e carregar os dados, conforme aprendemos na aula anterior.> Você deve colocar o diretório de acordo com o seu caminho no computador, e de acordo com a localização dos seus dados.```{r}# setwd("C:/Marina/Pos-doutorado/PNPD_UFPR/Vis Man Dados/Aula 2")# dados <- read.csv("Dados.csv")dados <- readr::read_csv('https://raw.githubusercontent.com/scalonmc/VisMan/master/VisManDados/Aula1/dados.csv')str(dados)```# Utilizando as funções do dplyr## SelectA função **select()** é importante para selecionar ou excluir variáveis (colunas do dataset)Abaixo, vamos fazer passo a passo:1. Selecionar apenas as variáveis categóricas2. Excluir variávies não úteis3. Condicional, no caso se a variável for numérica usando **is.numeric**4. Selecionar variávels com alguma característica comum utilizando **starts_with()** ou **ends_with()**5. Alterar ordem para visualização dos dados```{r}categoricas <-select(dados, Tratamento, especie, Grupo) #1str(categoricas)clean <-select(dados, -Amostra, -individuo) #2str(clean)numericas <-select_if(dados, is.numeric) #3ppm <-select(clean, ends_with("ppm")) #4str(ppm)ordered <-select(dados, N, P, everything())head(ordered)```## Rbase```Para fazer a mesma coisa no RbaseSão comandos bem simples que eu acho importante demostrarO diferencial é precisar verificar o número correspondente da coluna do dataframe``````{r}categoricas2 <- dados[2:4] #1str(categoricas2)clean2 <- dados[-c(1,5)] #2str(clean)nutri <- dados[6:13] #3str(nutri)```## SliceA função **slice()** é importante para selecionar ou excluir observações (linhas do dataset)Abaixo, vamos fazer passo a passo:1. Retirar linhas correspondentes a vegetação "Savana"2. Selecionar apenas as linhas correspondentes a vegetação "Savana"3. Selecionar n linhas em que a váriavel tem valor mínimo4. Selecionar n linhas em que uma variável tem um valor máximo```{r}sem.savana <-slice(clean, -46:-90)str(sem.savana)so.savana <-slice(clean, 46:90)str(so.savana)menosN <-slice_min(dados, N, n =5)head(menosN)maisAl <-slice_max(dados, Al_ppm, n =5)head(maisAl)```## Rbase```Para fazer a mesma coisa no RbaseSem usar a função **subset()** e usando a função **subset()**``````{r}so.savana2 <- clean[46:90,]so.savana3 <-subset(clean, Tratamento =="Savana")sem.savana2 <- clean[-(46:90),]sem.savana3 <-subset(clean, Tratamento !="Savana")```## FilterA função **filter()** funciona para seleção condicional de variáveis:::callout-note## NotaEla é equivalente a função **subset()** do Rbase - caso você esteja acostumado com ela!::: ```{r}deciduous <-filter(clean, Grupo =="D")deciduous2 <-subset(clean, Grupo =="D")```> Também é possível combinar as condições de filtro!Nesse caso estamos selecionando as espécies decíduas (D) apenas de Floresta com nitrogênio foliar maior que 2%```{r}deciduous.floresta.highN <-filter(clean, Grupo =="D"& Tratamento =="Floresta"& N >=2)str(deciduous.floresta.highN)```Verificar [operadores lógicos do R](https://d33wubrfki0l68.cloudfront.net/01f4b6d39d2be8269740a3ad7946faa79f7243cf/8369a/diagrams/transform-logical.png)> Operador %in%Para selecionar vários níveis dentro de uma variável```{r}sp <-filter(clean, especie %in%c("CB", "KC", "QP"))str(sp)```## RenameA função **rename()** é importante para mudar os nomes das variáveis. O nome atual vem antes do nome original.Vamos mudar os nomes para inglês.::: callout-tip## Dica!Quando o nome for espaçado ou tiver caracter especial ou número, deve estar entre o símbolo `:::```{r}ls(clean)new <-rename(clean, Vegetation = Tratamento, Species = especie, `Phenological group`= Grupo,Al = Al_ppm, `leaf area`= area, `leaf mass`= peso)ls(new)```## ArrangeA função **arrange()** permite colocarmos os dados em determinada ordem. Isso é importante principalmente para verificar tendências ou *outliers*Aqui vamos colocar os dados na ordem do maior valor de Al par ao menor para verificarmos as plantas acumuladoras de alumínio.Vamos usar a função head() para olhar como os dados foram ordenados do maior valor de Al.```{r}acumuladoras <-arrange (new, desc(Al))head(acumuladoras)```Mais interessante talvez seja ver esse padrão por algum grupo. Para isso arrange() pode ser muito útil.```{r}acumuladoras <-arrange(new, `Phenological group`, desc(Al))head(acumuladoras)```## MutateA função **mutate()** é muito utilizada para diversos objetivos de manipulação.Com ela, podemos:1. Transformar classes de objetos2. Mudar os nomes de variáveis ou de fatores 3. Criar novas variáveis ```{r}str(new)dados.factor <-mutate_if(new, is.character, as.factor) #1str(dados.factor)new.rename <-mutate(dados.factor, `Phenological group`=recode(`Phenological group`, D ="Deciduous", #2B ="Semideciduous", S ="Evergreen"),Vegetation =recode(Vegetation, Savana ="Savanna", Floresta ="Forest", Campo ="Grassland"))str(new.rename)final <-mutate(new.rename, SLA = (`leaf area`/`leaf mass`), `N:P`= N/P) #3```> A função **transmute()** equivale a mutate para criação de novas variáveis, porém só mantém a coluna da variável criada (não adiciona novas colunas)```{r}final.2<-transmute(new.rename, SLA = (`leaf area`/`leaf mass`))```## If_else Função muito útil para transformar variáveis junto com o *mutate()* de acordo com determinada condição, seguindo a mesma lógica da função equivalente no Rbase **ifelse()**: *ifelse(condição, sim, não)*::: callout-noteO diferencial é permitir lidar com valores faltantes!:::```{r}final3 <-mutate(final, classificação =if_else(Al>1000, "acumuladora", "não-acumuladora"))view(final3)```## Case_whenSimilar ao **if_else()**, mas permite mais condições! Perfeita para classificações ou agrupamentos de variáveis.```{r}final4 <-mutate(final, N_level =case_when( N <1~"very low",1< N & N <2~"low",2< N & N <3~"high", N >3~"very high"))```# PIPEO símbolo **%>%** conhecido como *pipe* é usado para unir as funções, podendo ser mentalmente substituído por "depois" ("then"). Dessa forma, não precisa se referir aos dados que estão sendo utilizados no início de cada função pois o pipe já assume que o produto de uma etapa é o impute da seguinte. Assim, organizar o seu código aplicando todos os comandos que fizemos acima, mas usando *pipe* reduz o número de linhas e deixa tudo mais limpo. Veja as etapas para chegar no dataset final:```{r}final.pipe <- dados %>%mutate_if(is.character, as.factor) %>%#mudar classe dos objetosselect(-Amostra, -individuo) %>%# eliminar colunas inuteisrename(Vegetation = Tratamento, Species = especie, `Phenological group`= Grupo,Al = Al_ppm, `leaf area`= area, `leaf mass`= peso) %>%#renomear variáveismutate(`Phenological group`=recode(`Phenological group`, D ="Deciduous", B ="Semideciduous", S ="Evergreen"),Vegetation =recode(Vegetation, Savana ="Savanna", Floresta ="Forest", Campo ="Grassland")) %>%# renomear os fatoresmutate(SLA=(`leaf area`/`leaf mass`), `N:P`= N/P) #criar novas variáveis summary(final.pipe)```::: callout-tip## Dica!Depois que você deixar os seus dados do jeito que você quer, salve novo arquivo de dados manipulados! Da próxima vez que você for usar conjunto da dados você já pode carregar o arquivo modificado e prontinho, sem passar pela etapa de manipulação novamente. Nunca substitua os dados originais! Use a função write.csv() e escreva sempre a extensão (.csv) no arquivo que será salvo.:::```{r}write.csv(final.pipe, "Dados_manipulados.csv")```## SummariseA função **summarise()** (ou **summarize()**) cria um novo dataframe colapsando valores em um sumário. **MUITO ÚTIL** pra fazer tabelas de médias, desvio padrão, etc.Usualmente utilizamos a função **group_by()** antes para especificar os grupos. Também pode ser combinada por summarise_all para aplicar a função em todas as variáveis.```{r}medias<- final.pipe %>%summarise(N =mean(N),P =mean(P))medias# Agrupando e aplicando em todas as colunasmedias2 <- final.pipe %>%group_by(Species, Vegetation, `Phenological group`) %>%summarise_all(mean) #médias por colunashead(medias2)```### Múltiplas funções```{r}tabela_mean <- final.pipe %>%select(-Species, -`Phenological group`)%>%group_by(Vegetation) %>%summarise_all(mean, na.rm=T)tabela1 <- final.pipe %>%select(-Species, -`Phenological group`) %>%group_by(Vegetation) %>%summarise_all(.funs =list(mean, sd))tabela2 <- final.pipe %>%select(-Species, -`Phenological group`) %>%group_by(Vegetation) %>%summarise_all(.funs =list(media = mean, desvio = sd))tabela3 <- final.pipe %>%select(-Species, -`Phenological group`) %>%group_by(Vegetation) %>%summarise_all(.funs =list(~mean(., na.rm=T), ~sd(., na.rm=T)))tabela_all2 <- final.pipe %>%group_by(Vegetation) %>%summarise(across(where(is.numeric), list(media=mean, desvio=sd),na.rm=T)) ```# Utilizando as funções do tidyrO tidyr tem apenas 4 funções principais! Vamos entender elas AGORA!## Pivot_longer (antiga funcão **gather()**)A funçao **pivot_longer()** empilha os dados. Ela é útil para arranjar os dados de forma que algum conjunto de variáveis torne-se um fator.Alguns tipos de gráficos (como gráficos de barras e boxplots) utilizam essa estrutura. Também pode ser importante para fazer gráficos separados em facetas, sendo que cada faceta seria relacionada a um fator.> Logicamente, TUDO depende da sua pergunta e do que você quer demostrar!!!Vamos usar pivot_longer() para juntar os nutrientes em uma única coluna.```{r}nutri <- medias2 %>%select(-`leaf area`, -`leaf mass`, -SLA, -Al, -`N:P`) %>%pivot_longer(4:8, names_to ="Nutriente", values_to ="media") head(nutri)boxplot(media~Nutriente, data=nutri)```## Pivot_wider (antiga função **spread()**)A função **pivot_wider** faz exatamente o oposto da função **pivot_longer**. Ela espalha os dados, tornando fatores novas variáveis.Vamos usar o pivot_wider para criar variáveis com os diferentes grupos fenológicos```{r}grupos <- nutri %>%pivot_wider(names_from=Vegetation, values_from = media)head(grupos)```## UniteA função **unite** junta, como o próprio nome diz, duas ou mais colunas em uma só.Vamos juntar os fatores para criar uma variável de interação com grupo e tratamento, especificando um separador, no caso _ .```{r}inter <- medias2 %>%unite("Interaction", `Phenological group`, Vegetation, sep="_")head(inter)```## SeparateA função **separate** faz o oposto da função **unite**, separando as colunas em 1 ou mais colunas.Vamos demostrar de algumas formas:1. Separando as variáveis que acabamos de juntar no exemplo anterior2. Separando as iniciais da variável espécie entre a inicial do gênero e a inicial do epípeto específico,```{r}inter %>%separate(Interaction, into =c("Grupo", "Tipo"), sep ="_")inter %>%separate(Species, into =c("Genero", "Epípeto"), sep =1)```# Leitura complementar- Capítulos [Data transformatio](https://r4ds.had.co.nz/transform.html) e [Tidy Data](https://r4ds.had.co.nz/tidy-data.html) do livro [R for Data Science](https://r4ds.had.co.nz/index.html)- [Manipulating Data](https://r-unimelb.gitbook.io/rbook/into-the-tidyverse/manipulating-data-with-dplyr)- A própria documentação dos pacotes é bem completa! [tidyr](https://tidyr.tidyverse.org/articles/tidy-data.html) ou [dplyr](https://dplyr.tidyverse.org/articles/dplyr.html)# FIM