Questo documento ripercorre il documento su R denominato R for Excel.
E’ stato pubblicato su RPubs
Per utilizzare del codice bisogna metterlo in 3 backsticks.
Posso avere diverse opzioni:
Ovviamente si può fare l’embedded del codice. Si può decidere di mettere echo in FALSE o TRUE. Una cosa molto interessante è che si possono mettere le etichette nei pezzi di codice. Ogni etichetta deve essere univoca. Probabilmente se ne vedrà l’utilizzo in seguito ma per ora ecco il risultato:
summary(cars)## speed dist
## Min. : 4.0 Min. : 2.00
## 1st Qu.:12.0 1st Qu.: 26.00
## Median :15.0 Median : 36.00
## Mean :15.4 Mean : 42.98
## 3rd Qu.:19.0 3rd Qu.: 56.00
## Max. :25.0 Max. :120.00
Per importare i files di Excel è possibile usare
read_excel oppure utilizzando il pacchetto
tidyverse possiamo trovare readr e readxl.
ca_np <- suppressMessages(
read_csv(here("Input/Excel", "ca_np.csv"))
)
ci_np <- suppressMessages(
read_excel(here("Input/Excel", "ci_np.xlsx"))
)Possiamo successivamente vedere:
names(ca_np)## [1] "region" "state" "code" "park_name" "type" "visitors"
## [7] "year"
head(ca_np)## # A tibble: 6 × 7
## region state code park_name type visitors year
## <chr> <chr> <chr> <chr> <chr> <dbl> <dbl>
## 1 PW CA CHIS Channel Islands National Park National Park 1200 1963
## 2 PW CA CHIS Channel Islands National Park National Park 1500 1964
## 3 PW CA CHIS Channel Islands National Park National Park 1600 1965
## 4 PW CA CHIS Channel Islands National Park National Park 300 1966
## 5 PW CA CHIS Channel Islands National Park National Park 15700 1967
## 6 PW CA CHIS Channel Islands National Park National Park 31000 1968
summary(ca_np)## region state code park_name
## Length:789 Length:789 Length:789 Length:789
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
## type visitors year
## Length:789 Min. : 300 Min. :1904
## Class :character 1st Qu.: 111385 1st Qu.:1946
## Mode :character Median : 393219 Median :1973
## Mean : 607632 Mean :1970
## 3rd Qu.: 797800 3rd Qu.:1995
## Max. :5028868 Max. :2016
Fa parte del pacchetto tidyverse. Servono:
Per creare un grafico a barre bisogna:
ggplot2::ggplot()grafico = ggplot(
data = ci_np,
aes(x=year,y=visitors)
)
grafico + geom_line()Prima di tutto customizziamo l’aesthetic con colori, stili, titoli negli assi etc.
grafico + geom_line(
color = "red"
)+
geom_point(
color = "purple",
size=4,
pch=17,
alpha = 0.5
)Per modificare la grandezza ed il colore in maniera dinamica anzichè fissa come fatto sopra, si supponga uno scatterplot
grafico + geom_point(
aes(size = visitors,
color = visitors),
alpha = 0.5
)Interessante anche l’utilizzo di fill che modifica il colore in base al numero.
grafico + geom_col(
aes(fill = visitors))Posso, inoltre, utilizzare dei temi.
grafico + geom_point(aes(size = visitors,
color = visitors),
alpha = 0.5
) +
theme_bw()In molti casi, inoltre, è possibile modificare i titoli e le
etichette degli assi. Per fare ciò si utilizza labs
grafico+ geom_line(linetype = "dotted") +
theme_bw() +
labs(
x = "Anni",
y = "Visitatori annui",
title = "Canale Islands NP Visitation",
subtitle = "(1963 - 2016)"
)Come abbiamo già visto anche in precedenza, è pure possibile sovrapporre grafici compatibili
grafico+
geom_col(fill = "gray",
color = "grey") +
geom_line(color = "red")Nel caso si abbiano multiple serie, è possibile letteralmente raggrupparle per avere grafici multipli all’interno dello stesso
grafico2 <- ggplot(
data = ca_np,
aes(x = year, y = visitors,group = park_name)
)
grafico2 + geom_line()In teoria, dentro geom_line posso usare un
color = park_name ma mi restituisce errore…
Per creare grafici multipli devo usare il faceting.
grafico2+geom_line(show.legend = FALSE) +
theme_light() +
labs(x = "year", y = "annual visitors") +
facet_wrap(~ park_name, nrow = 2)Infine si possono salvare i grafici con
ggsave(here("figures", "np_graph.jpg"), dpi = 180, width = 8, height = 7)
Il pacchetto dplyr permette di elaborare i dati in modo molto efficiente e di creare delle tabelle pivot.
OTTIMO CHEATSHEET qui
In questo caso utilizziamo i file lobsters dove le prime righe sono “rumore” rispetto ai dati. Le prime tre righe sono metadati e le informazioni iniziano dalla riga 5.
lobsters <- read_xlsx(here("Input/Excel","lobsters.xlsx"), skip=4)Una volta importata la base dati, abbiamo usato summary
per avere una descrizione del dataset. Questa funzione, però, ignora i
campi testuali e quindi utilizzo il macchetto skimr.
skimmata <- skim(lobsters)
skimmata| Name | lobsters |
| Number of rows | 2893 |
| Number of columns | 7 |
| _______________________ | |
| Column type frequency: | |
| character | 3 |
| numeric | 4 |
| ________________________ | |
| Group variables | None |
Variable type: character
| skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
|---|---|---|---|---|---|---|---|
| date | 0 | 1 | 6 | 7 | 0 | 28 | 0 |
| site | 0 | 1 | 4 | 4 | 0 | 5 | 0 |
| replicate | 0 | 1 | 1 | 1 | 0 | 4 | 0 |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| year | 0 | 1 | 2014.70 | 1.19 | 2012 | 2014 | 2015 | 2016 | 2016 | ▂▂▃▇▆ |
| month | 0 | 1 | 8.04 | 0.19 | 8 | 8 | 8 | 8 | 9 | ▇▁▁▁▁ |
| transect | 0 | 1 | 3.72 | 2.30 | 1 | 2 | 3 | 5 | 9 | ▇▅▃▂▂ |
| size_mm | 5 | 1 | 71.38 | 14.75 | 18 | 62 | 72 | 81 | 165 | ▁▇▆▁▁ |
Supponiamo ci venga chiesto come la dimensione media del lobster sia cambiata per ogni sito durante il tempo.
Per fare ciò usiamo group_by e summarize. E’ sempre
importante eliminare gli NA se non necessari:
siteyear_summary <- lobsters %>%
group_by(site, year) %>%
summarize(
count_by_siteyear = n(),
mean_size_mm = mean(size_mm, na.rm=TRUE),
sd_size_mm = sd(size_mm, na.rm=TRUE)
)## `summarise()` has grouped output by 'site'. You can override using the
## `.groups` argument.
siteyear_summary## # A tibble: 25 × 5
## # Groups: site [5]
## site year count_by_siteyear mean_size_mm sd_size_mm
## <chr> <dbl> <int> <dbl> <dbl>
## 1 aque 2012 38 71 10.2
## 2 aque 2013 32 72.1 12.3
## 3 aque 2014 100 76.9 9.32
## 4 aque 2015 83 68.5 12.6
## 5 aque 2016 48 68.7 12.5
## 6 carp 2012 78 74.4 14.6
## 7 carp 2013 93 76.6 8.71
## 8 carp 2014 79 79.1 8.57
## 9 carp 2015 90 70.7 14.6
## 10 carp 2016 231 68.9 12.5
## # … with 15 more rows
Adesso vogliamo mettere questa variabile in una tabella fatta meglio.
Per questo utilizziamo kable
siteyear_summary %>%
kable()| site | year | count_by_siteyear | mean_size_mm | sd_size_mm |
|---|---|---|---|---|
| aque | 2012 | 38 | 71.00000 | 10.150223 |
| aque | 2013 | 32 | 72.12500 | 12.262584 |
| aque | 2014 | 100 | 76.92000 | 9.321074 |
| aque | 2015 | 83 | 68.45783 | 12.555536 |
| aque | 2016 | 48 | 68.68750 | 12.510687 |
| carp | 2012 | 78 | 74.35897 | 14.616282 |
| carp | 2013 | 93 | 76.56989 | 8.709562 |
| carp | 2014 | 79 | 79.08974 | 8.569329 |
| carp | 2015 | 90 | 70.65556 | 14.646517 |
| carp | 2016 | 231 | 68.90476 | 12.470122 |
| ivee | 2012 | 26 | 66.07692 | 12.092719 |
| ivee | 2013 | 40 | 73.77500 | 7.640941 |
| ivee | 2014 | 132 | 76.02273 | 17.860984 |
| ivee | 2015 | 361 | 69.80332 | 17.470534 |
| ivee | 2016 | 193 | 71.61658 | 13.450454 |
| mohk | 2012 | 83 | 77.25301 | 10.587433 |
| mohk | 2013 | 15 | 71.86667 | 10.190098 |
| mohk | 2014 | 36 | 75.75000 | 10.038142 |
| mohk | 2015 | 296 | 59.19932 | 16.770357 |
| mohk | 2016 | 210 | 63.01286 | 11.875763 |
| napl | 2012 | 6 | 73.00000 | 11.747340 |
| napl | 2013 | 63 | 75.31746 | 12.989854 |
| napl | 2014 | 163 | 79.51572 | 9.556531 |
| napl | 2015 | 270 | 78.24074 | 12.438899 |
| napl | 2016 | 127 | 74.39370 | 10.732060 |
Vediamo anche la situazione con il codice inline che sarebbe molto interessante per vedere, ad esempio, quante righe ha il nostro dataframe: 2893.
Nessuno ci vieta di mettere a grafico la variabile così ottenuta. Questa volta metto color all’interno della aesthetic in modo da vedere curve con colori differenti.
Prova a mettere e togliere il comando delle palette. Ecco alcuni nomi: in questo sito
siteyear_summary %>% ggplot(
aes(
x=year, y=mean_size_mm, color = site
)
) + labs(
x = "Anno",
y = "Media",
title = "Media per anno"
)+geom_line()+
scale_color_paletteer_d("RColorBrewer::RdGy") ggsave(here("Output/OutputExcel", "lobsters-line.png"))## Saving 7 x 5 in image
Altre interessantissime funzioni di dplyr sono:
Mutate serve per aggiungere informazioni
lobsters_detailed <- lobsters %>%
mutate(size_m = size_mm / 1000,
millenia = 2000,
observer = "Allison Horst")Select per fare select in stile SQL ma senza FILTRO.
lobsters_detailed %>%
select(date, site, size_m)## # A tibble: 2,893 × 3
## date site size_m
## <chr> <chr> <dbl>
## 1 8/20/12 ivee 0.07
## 2 8/20/12 ivee 0.06
## 3 8/20/12 ivee 0.065
## 4 8/20/12 ivee 0.07
## 5 8/20/12 ivee 0.085
## 6 8/20/12 ivee 0.06
## 7 8/20/12 ivee 0.065
## 8 8/20/12 ivee 0.067
## 9 8/20/12 ivee 0.07
## 10 8/20/12 ivee 0.085
## # … with 2,883 more rows
In questa sezione impariamo a rimodellare i dataframe, a separare ed unire le variabili e trovare e modificare i pattern di stringa.
Qui andremo ad analizzare: - tidyr::pivot_wider() e
tidyr::pivot_longer() per rimodellare i data frames -
janitor::clean_names() per rendere i titoli di colonna più
maneggiabili - tidyr::unite() e
tidyr::separate() per merge or separate informazioni da
differenti colonne - Trovare e modificare una stringa con le funzioni
stringr
Prima di tutto iniziamo a leggere il file che mi interessa:
inverts <- read_excel(here("Input/Excel", "inverts.xlsx"))A questo punto tidyr::pivot_longer funziona come lo
unpivot di powerquery. Si veda prima il dataframe quali
dati contiene:
head(inverts)## # A tibble: 6 × 6
## month site common_name `2016` `2017` `2018`
## <chr> <chr> <chr> <dbl> <dbl> <dbl>
## 1 7 abur california cone snail 451 28 762
## 2 7 abur california spiny lobster 17 17 16
## 3 7 abur orange cup coral 24 24 24
## 4 7 abur purple urchin 48 48 48
## 5 7 abur rock scallop 16 16 16
## 6 7 ahnd california cone snail 27 24 24
A questo punto il contenuto degli anni viene messo in riga anzichè colonna proprio come un unpivot:
inverts_long <- pivot_longer(data = inverts,
cols = '2016':'2018',
names_to = "year",
values_to = "sp_count")Si faccia attenzione al fatto che l’anno non viene automaticamente convertito in numerico. Questo perchè prima era un’intestazione ovvero un testo. Per accertarsene:
class(inverts_long$year)## [1] "character"
Quindi posso modificarla con dyplr
inverts_long <- inverts_long %>%
mutate(year = as.numeric(year))
class(inverts_long$year)## [1] "numeric"
L’esatto contrario ovvero il pivottare in colonna si fa con
il pivot_wider:
inverts_wide <- inverts_long %>%
pivot_wider(names_from = common_name,
values_from = sp_count)La funzione janitor::clean_names serve per pulire i nomi
di colonna. Il pacchetto janitor è un ottimo pacchetto
di pulizia:
janitor::clean_names(): update column headers to a case
of your choosing
janitor::get_dupes(): see all rows that are duplicates
within variables you choosejanitor::remove_empty(): remove empty rows and/or
columnsjanitor::adorn_*(): jazz up tablesAlcuni esempi del clean_names:
inverts_wide <- inverts_wide %>%
clean_names("upper_camel")
names(inverts_wide)## [1] "Month" "Site" "Year"
## [4] "CaliforniaConeSnail" "CaliforniaSpinyLobster" "OrangeCupCoral"
## [7] "PurpleUrchin" "RockScallop"
A questo punto arriviamo a tidyr::unite e
tidyr::separate
Ecco unite:
inverts_unite <- inverts_long %>%
unite(
col = "site_year", # Il nome della nuova colonna
c(site, year), # Le colonne da unire
sep = "_") # Il separatoreEcco separate:
inverts_sep <- inverts_unite %>%
tidyr::separate(
site_year,
into = c("my_site", "my_year"), sep = "_")Ultima funzione è modificare una stringa in base ad un pattern.
ca_abbr <- inverts %>%
mutate(
common_name =
str_replace(common_name,
pattern = "california",
replacement = "CA")
)In questa sezione andiamo ad analizzare
filter() e la sua pagina di
riferimento*_join() e pagina di
riferimentokable()Mentre le funzione filter() è simile ai filtri su Excel, la funzione *_join()* è l’evoluzione dei cerca.vert di Excel.
Come sempre, iniziamo a leggere le basi dati:
fish <- read_csv(here("Input/Excel", "fish.csv"))## Rows: 45 Columns: 4
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (2): site, common_name
## dbl (2): year, total_count
##
## ℹ 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.
kelp_abur <- read_excel(here("Input/Excel", "kelp_fronds.xlsx"), sheet = "abur")Abituiamoci a esplorare sempre i dati con queste funzioni:
names(fish)## [1] "year" "site" "common_name" "total_count"
summary(fish)## year site common_name total_count
## Min. :2016 Length:45 Length:45 Min. : 1.00
## 1st Qu.:2016 Class :character Class :character 1st Qu.: 1.00
## Median :2017 Mode :character Mode :character Median : 2.00
## Mean :2017 Mean :11.36
## 3rd Qu.:2018 3rd Qu.: 8.00
## Max. :2018 Max. :64.00
head(fish)## # A tibble: 6 × 4
## year site common_name total_count
## <dbl> <chr> <chr> <dbl>
## 1 2016 abur black surfperch 2
## 2 2016 abur blacksmith 1
## 3 2016 abur garibaldi 1
## 4 2016 abur rock wrasse 2
## 5 2016 abur senorita 58
## 6 2016 aque black surfperch 1
tail(fish)## # A tibble: 6 × 4
## year site common_name total_count
## <dbl> <chr> <chr> <dbl>
## 1 2018 aque senorita 36
## 2 2018 mohk black surfperch 32
## 3 2018 mohk blacksmith 31
## 4 2018 mohk garibaldi 10
## 5 2018 mohk rock wrasse 4
## 6 2018 mohk senorita 4
Filter serve per filtrare la base dati e dirgli cosa voglio e cosa voglio escludere.
Supponiamo di volere solo i common_fish denominati garibaldi
fish_garibaldi <- fish %>%
filter( common_name == "garibaldi")Le clausole per i numeri sono le solite degli altri linguaggi:
fish_over50 <- fish %>%
filter(total_count>=50)Ovviamente posso utilizzare sia clausole di tipo OR sia di tipo AND.
Vediamo la OR; è possibile esprimere la OR con un
|:
fish_3sp <- fish %>%
filter(common_name == "garibaldi" |
common_name == "blacksmith" |
common_name == "black surfperch") Un’alternativa è l’utilizzo dell’operatore %in%.
fish_2sp_in <- fish %>%
filter(common_name %in% c("garibaldi","blacksmith"))Ci sono diverse metodologie per fare degli AND.
&fish %>% filter(year == 2018, site=="aque")## # A tibble: 5 × 4
## year site common_name total_count
## <dbl> <chr> <chr> <dbl>
## 1 2018 aque black surfperch 2
## 2 2018 aque blacksmith 1
## 3 2018 aque garibaldi 1
## 4 2018 aque rock wrasse 4
## 5 2018 aque senorita 36
fish %>% filter(year==2018 & site=="aque")## # A tibble: 5 × 4
## year site common_name total_count
## <dbl> <chr> <chr> <dbl>
## 1 2018 aque black surfperch 2
## 2 2018 aque blacksmith 1
## 3 2018 aque garibaldi 1
## 4 2018 aque rock wrasse 4
## 5 2018 aque senorita 36
fish %>% filter(year==2018) %>% filter(site=="aque")## # A tibble: 5 × 4
## year site common_name total_count
## <dbl> <chr> <chr> <dbl>
## 1 2018 aque black surfperch 2
## 2 2018 aque blacksmith 1
## 3 2018 aque garibaldi 1
## 4 2018 aque rock wrasse 4
## 5 2018 aque senorita 36
Può essere necessario selezionare un campo con un pattern di stringa
anzichè una stringa precisa. A tal fine è utile
stringr::str_detect()
fish %>%
filter(str_detect(common_name, pattern = "black"))## # A tibble: 18 × 4
## year site common_name total_count
## <dbl> <chr> <chr> <dbl>
## 1 2016 abur black surfperch 2
## 2 2016 abur blacksmith 1
## 3 2016 aque black surfperch 1
## 4 2016 aque blacksmith 1
## 5 2016 mohk black surfperch 1
## 6 2016 mohk blacksmith 1
## 7 2017 abur black surfperch 4
## 8 2017 abur blacksmith 1
## 9 2017 aque black surfperch 1
## 10 2017 aque blacksmith 1
## 11 2017 mohk black surfperch 50
## 12 2017 mohk blacksmith 8
## 13 2018 abur black surfperch 1
## 14 2018 abur blacksmith 1
## 15 2018 aque black surfperch 2
## 16 2018 aque blacksmith 1
## 17 2018 mohk black surfperch 32
## 18 2018 mohk blacksmith 31
Esistono diversi tipi di join che corrispondono a dei cerca.vert tra i quali:
abur_kelp_fish <- fish_over50 %>%
full_join(fish, by = c("year", "site"))
abur_kelp_fish## # A tibble: 50 × 6
## year site common_name.x total_count.x common_name.y total_count.y
## <dbl> <chr> <chr> <dbl> <chr> <dbl>
## 1 2016 abur senorita 58 black surfperch 2
## 2 2016 abur senorita 58 blacksmith 1
## 3 2016 abur senorita 58 garibaldi 1
## 4 2016 abur senorita 58 rock wrasse 2
## 5 2016 abur senorita 58 senorita 58
## 6 2016 aque senorita 57 black surfperch 1
## 7 2016 aque senorita 57 blacksmith 1
## 8 2016 aque senorita 57 garibaldi 1
## 9 2016 aque senorita 57 rock wrasse 1
## 10 2016 aque senorita 57 senorita 57
## # … with 40 more rows
Interessante mettere tutti questi comandi all’interno di un’unica istruzione:
my_fish_join <- fish %>%
filter(year == 2017, site == "abur") %>%
left_join(abur_kelp_fish, by = c("year", "site")) %>%
mutate(fish_per_frond = total_count/100 )
my_fish_join## # A tibble: 50 × 9
## year site common_name total_c…¹ commo…² total…³ commo…⁴ total…⁵ fish_…⁶
## <dbl> <chr> <chr> <dbl> <chr> <dbl> <chr> <dbl> <dbl>
## 1 2017 abur black surfperch 4 rock w… 57 black … 4 0.04
## 2 2017 abur black surfperch 4 rock w… 57 blacks… 1 0.04
## 3 2017 abur black surfperch 4 rock w… 57 gariba… 1 0.04
## 4 2017 abur black surfperch 4 rock w… 57 rock w… 57 0.04
## 5 2017 abur black surfperch 4 rock w… 57 senori… 64 0.04
## 6 2017 abur black surfperch 4 senori… 64 black … 4 0.04
## 7 2017 abur black surfperch 4 senori… 64 blacks… 1 0.04
## 8 2017 abur black surfperch 4 senori… 64 gariba… 1 0.04
## 9 2017 abur black surfperch 4 senori… 64 rock w… 57 0.04
## 10 2017 abur black surfperch 4 senori… 64 senori… 64 0.04
## # … with 40 more rows, and abbreviated variable names ¹total_count,
## # ²common_name.x, ³total_count.x, ⁴common_name.y, ⁵total_count.y,
## # ⁶fish_per_frond
E’ molto importante avere delle tabelle ben formattate. A questo
proposito ci viene in aiuto kableExtra.
Prendo il risultato di prima e lo inserisco in una tabella ben formattata:
my_fish_join %>%
kbl() %>%
kable_classic_2(full_width = F)| year | site | common_name | total_count | common_name.x | total_count.x | common_name.y | total_count.y | fish_per_frond |
|---|---|---|---|---|---|---|---|---|
| 2017 | abur | black surfperch | 4 | rock wrasse | 57 | black surfperch | 4 | 0.04 |
| 2017 | abur | black surfperch | 4 | rock wrasse | 57 | blacksmith | 1 | 0.04 |
| 2017 | abur | black surfperch | 4 | rock wrasse | 57 | garibaldi | 1 | 0.04 |
| 2017 | abur | black surfperch | 4 | rock wrasse | 57 | rock wrasse | 57 | 0.04 |
| 2017 | abur | black surfperch | 4 | rock wrasse | 57 | senorita | 64 | 0.04 |
| 2017 | abur | black surfperch | 4 | senorita | 64 | black surfperch | 4 | 0.04 |
| 2017 | abur | black surfperch | 4 | senorita | 64 | blacksmith | 1 | 0.04 |
| 2017 | abur | black surfperch | 4 | senorita | 64 | garibaldi | 1 | 0.04 |
| 2017 | abur | black surfperch | 4 | senorita | 64 | rock wrasse | 57 | 0.04 |
| 2017 | abur | black surfperch | 4 | senorita | 64 | senorita | 64 | 0.04 |
| 2017 | abur | blacksmith | 1 | rock wrasse | 57 | black surfperch | 4 | 0.01 |
| 2017 | abur | blacksmith | 1 | rock wrasse | 57 | blacksmith | 1 | 0.01 |
| 2017 | abur | blacksmith | 1 | rock wrasse | 57 | garibaldi | 1 | 0.01 |
| 2017 | abur | blacksmith | 1 | rock wrasse | 57 | rock wrasse | 57 | 0.01 |
| 2017 | abur | blacksmith | 1 | rock wrasse | 57 | senorita | 64 | 0.01 |
| 2017 | abur | blacksmith | 1 | senorita | 64 | black surfperch | 4 | 0.01 |
| 2017 | abur | blacksmith | 1 | senorita | 64 | blacksmith | 1 | 0.01 |
| 2017 | abur | blacksmith | 1 | senorita | 64 | garibaldi | 1 | 0.01 |
| 2017 | abur | blacksmith | 1 | senorita | 64 | rock wrasse | 57 | 0.01 |
| 2017 | abur | blacksmith | 1 | senorita | 64 | senorita | 64 | 0.01 |
| 2017 | abur | garibaldi | 1 | rock wrasse | 57 | black surfperch | 4 | 0.01 |
| 2017 | abur | garibaldi | 1 | rock wrasse | 57 | blacksmith | 1 | 0.01 |
| 2017 | abur | garibaldi | 1 | rock wrasse | 57 | garibaldi | 1 | 0.01 |
| 2017 | abur | garibaldi | 1 | rock wrasse | 57 | rock wrasse | 57 | 0.01 |
| 2017 | abur | garibaldi | 1 | rock wrasse | 57 | senorita | 64 | 0.01 |
| 2017 | abur | garibaldi | 1 | senorita | 64 | black surfperch | 4 | 0.01 |
| 2017 | abur | garibaldi | 1 | senorita | 64 | blacksmith | 1 | 0.01 |
| 2017 | abur | garibaldi | 1 | senorita | 64 | garibaldi | 1 | 0.01 |
| 2017 | abur | garibaldi | 1 | senorita | 64 | rock wrasse | 57 | 0.01 |
| 2017 | abur | garibaldi | 1 | senorita | 64 | senorita | 64 | 0.01 |
| 2017 | abur | rock wrasse | 57 | rock wrasse | 57 | black surfperch | 4 | 0.57 |
| 2017 | abur | rock wrasse | 57 | rock wrasse | 57 | blacksmith | 1 | 0.57 |
| 2017 | abur | rock wrasse | 57 | rock wrasse | 57 | garibaldi | 1 | 0.57 |
| 2017 | abur | rock wrasse | 57 | rock wrasse | 57 | rock wrasse | 57 | 0.57 |
| 2017 | abur | rock wrasse | 57 | rock wrasse | 57 | senorita | 64 | 0.57 |
| 2017 | abur | rock wrasse | 57 | senorita | 64 | black surfperch | 4 | 0.57 |
| 2017 | abur | rock wrasse | 57 | senorita | 64 | blacksmith | 1 | 0.57 |
| 2017 | abur | rock wrasse | 57 | senorita | 64 | garibaldi | 1 | 0.57 |
| 2017 | abur | rock wrasse | 57 | senorita | 64 | rock wrasse | 57 | 0.57 |
| 2017 | abur | rock wrasse | 57 | senorita | 64 | senorita | 64 | 0.57 |
| 2017 | abur | senorita | 64 | rock wrasse | 57 | black surfperch | 4 | 0.64 |
| 2017 | abur | senorita | 64 | rock wrasse | 57 | blacksmith | 1 | 0.64 |
| 2017 | abur | senorita | 64 | rock wrasse | 57 | garibaldi | 1 | 0.64 |
| 2017 | abur | senorita | 64 | rock wrasse | 57 | rock wrasse | 57 | 0.64 |
| 2017 | abur | senorita | 64 | rock wrasse | 57 | senorita | 64 | 0.64 |
| 2017 | abur | senorita | 64 | senorita | 64 | black surfperch | 4 | 0.64 |
| 2017 | abur | senorita | 64 | senorita | 64 | blacksmith | 1 | 0.64 |
| 2017 | abur | senorita | 64 | senorita | 64 | garibaldi | 1 | 0.64 |
| 2017 | abur | senorita | 64 | senorita | 64 | rock wrasse | 57 | 0.64 |
| 2017 | abur | senorita | 64 | senorita | 64 | senorita | 64 | 0.64 |
IMPORTANTE: questo documento spiega come fare delle ottime tabelle in kable
Porca miseria!! Il pacchetto reprex() serve per creare un esempio del codice del quale trovare una soluzione sul web.