This report provides an exploratory analysis of the global crocodile species dataset. It includes data loading, summary statistics, and visualizations.
The dataset provides a comprehensive view of species diversity, ecological distribution, and population characteristics of crocodiles.
Certain species and families dominate observations, indicating either higher abundance or observer focus.
Quantitative traits such as length and weight align with biological expectations, while temporal and habitat-based patterns reveal ecological and observational trends.
Observer activity analysis highlights the contribution of a few key individuals in collecting most of the data.
##Install necessary packages
install.packages(c("tydiverse","janitor","shiny", "flexdashboard", "shinydashboard", "bs4Dash", "plotly", "leaflet", "highcharter"))
## Installing packages into '/cloud/lib/x86_64-pc-linux-gnu-library/4.5'
## (as 'lib' is unspecified)
## Warning: package 'tydiverse' is not available for this version of R
##
## A version of this package for your version of R might be available elsewhere,
## see the ideas at
## https://cran.r-project.org/doc/manuals/r-patched/R-admin.html#Installing-packages
##Recognize packages
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.1 ✔ stringr 1.5.2
## ✔ ggplot2 4.0.0 ✔ tibble 3.3.0
## ✔ lubridate 1.9.4 ✔ tidyr 1.3.1
## ✔ purrr 1.1.0
## ── 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
library(janitor)
##
## Attaching package: 'janitor'
##
## The following objects are masked from 'package:stats':
##
## chisq.test, fisher.test
library(readxl)
library(shiny)
library(flexdashboard)
library(shinydashboard)
##
## Attaching package: 'shinydashboard'
##
## The following objects are masked from 'package:flexdashboard':
##
## renderValueBox, valueBox, valueBoxOutput
##
## The following object is masked from 'package:graphics':
##
## box
library(bs4Dash)
##
## Attaching package: 'bs4Dash'
##
## The following objects are masked from 'package:shinydashboard':
##
## box, dashboardBody, dashboardHeader, dashboardPage,
## dashboardSidebar, dropdownMenu, dropdownMenuOutput, infoBox,
## infoBoxOutput, menuItem, menuItemOutput, menuSubItem, messageItem,
## notificationItem, renderInfoBox, renderMenu, renderValueBox,
## sidebarMenu, sidebarMenuOutput, sidebarUserPanel, tabBox, tabItem,
## tabItems, taskItem, updateTabItems, valueBox, valueBoxOutput
##
## The following objects are masked from 'package:flexdashboard':
##
## renderValueBox, valueBox, valueBoxOutput
##
## The following objects are masked from 'package:shiny':
##
## actionButton, column, insertTab, navbarMenu, tabsetPanel
##
## The following object is masked from 'package:graphics':
##
## box
library(plotly)
##
## Attaching package: 'plotly'
##
## The following object is masked from 'package:ggplot2':
##
## last_plot
##
## The following object is masked from 'package:stats':
##
## filter
##
## The following object is masked from 'package:graphics':
##
## layout
library(leaflet)
library(highcharter)
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
## Highcharts (www.highcharts.com) is a Highsoft software product which is
## not free for commercial and Governmental use
crocodile_species <- read.csv("crocodile_dataset.csv")
glimpse(crocodile_species)
## Rows: 1,000
## Columns: 15
## $ Observation.ID <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15…
## $ Common.Name <chr> "Morelet's Crocodile", "American Crocodile", "Ori…
## $ Scientific.Name <chr> "Crocodylus moreletii", "Crocodylus acutus", "Cro…
## $ Family <chr> "Crocodylidae", "Crocodylidae", "Crocodylidae", "…
## $ Genus <chr> "Crocodylus", "Crocodylus", "Crocodylus", "Crocod…
## $ Observed.Length..m. <dbl> 1.90, 4.09, 1.08, 2.42, 3.75, 2.64, 2.85, 0.35, 3…
## $ Observed.Weight..kg. <dbl> 62.0, 334.5, 118.2, 90.4, 269.4, 137.4, 157.7, 4.…
## $ Age.Class <chr> "Adult", "Adult", "Juvenile", "Adult", "Adult", "…
## $ Sex <chr> "Male", "Male", "Unknown", "Male", "Unknown", "Ma…
## $ Date.of.Observation <chr> "31-03-2018", "28-01-2015", "07-12-2010", "01-11-…
## $ Country.Region <chr> "Belize", "Venezuela", "Venezuela", "Mexico", "In…
## $ Habitat.Type <chr> "Swamps", "Mangroves", "Flooded Savannas", "River…
## $ Conservation.Status <chr> "Least Concern", "Vulnerable", "Critically Endang…
## $ Observer.Name <chr> "Allison Hill", "Brandon Hall", "Melissa Peterson…
## $ Notes <chr> "Cause bill scientist nation opportunity.", "Ago …
colnames(crocodile_species)
## [1] "Observation.ID" "Common.Name" "Scientific.Name"
## [4] "Family" "Genus" "Observed.Length..m."
## [7] "Observed.Weight..kg." "Age.Class" "Sex"
## [10] "Date.of.Observation" "Country.Region" "Habitat.Type"
## [13] "Conservation.Status" "Observer.Name" "Notes"
summary(crocodile_species)
## Observation.ID Common.Name Scientific.Name Family
## Min. : 1.0 Length:1000 Length:1000 Length:1000
## 1st Qu.: 250.8 Class :character Class :character Class :character
## Median : 500.5 Mode :character Mode :character Mode :character
## Mean : 500.5
## 3rd Qu.: 750.2
## Max. :1000.0
## Genus Observed.Length..m. Observed.Weight..kg. Age.Class
## Length:1000 Min. :0.140 Min. : 4.40 Length:1000
## Class :character 1st Qu.:1.637 1st Qu.: 53.23 Class :character
## Mode :character Median :2.430 Median : 100.60 Mode :character
## Mean :2.415 Mean : 155.77
## 3rd Qu.:3.010 3rd Qu.: 168.88
## Max. :6.120 Max. :1139.70
## Sex Date.of.Observation Country.Region Habitat.Type
## Length:1000 Length:1000 Length:1000 Length:1000
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
## Conservation.Status Observer.Name Notes
## Length:1000 Length:1000 Length:1000
## Class :character Class :character Class :character
## Mode :character Mode :character Mode :character
##
##
##
head(crocodile_species)
## Observation.ID Common.Name Scientific.Name
## 1 1 Morelet's Crocodile Crocodylus moreletii
## 2 2 American Crocodile Crocodylus acutus
## 3 3 Orinoco Crocodile Crocodylus intermedius
## 4 4 Morelet's Crocodile Crocodylus moreletii
## 5 5 Mugger Crocodile (Marsh Crocodile) Crocodylus palustris
## 6 6 Mugger Crocodile (Marsh Crocodile) Crocodylus palustris
## Family Genus Observed.Length..m. Observed.Weight..kg. Age.Class
## 1 Crocodylidae Crocodylus 1.90 62.0 Adult
## 2 Crocodylidae Crocodylus 4.09 334.5 Adult
## 3 Crocodylidae Crocodylus 1.08 118.2 Juvenile
## 4 Crocodylidae Crocodylus 2.42 90.4 Adult
## 5 Crocodylidae Crocodylus 3.75 269.4 Adult
## 6 Crocodylidae Crocodylus 2.64 137.4 Adult
## Sex Date.of.Observation Country.Region Habitat.Type
## 1 Male 31-03-2018 Belize Swamps
## 2 Male 28-01-2015 Venezuela Mangroves
## 3 Unknown 07-12-2010 Venezuela Flooded Savannas
## 4 Male 01-11-2019 Mexico Rivers
## 5 Unknown 15-07-2019 India Rivers
## 6 Male 08-06-2023 India Reservoirs
## Conservation.Status Observer.Name
## 1 Least Concern Allison Hill
## 2 Vulnerable Brandon Hall
## 3 Critically Endangered Melissa Peterson
## 4 Least Concern Edward Fuller
## 5 Vulnerable Donald Reid
## 6 Vulnerable Randy Brown
## Notes
## 1 Cause bill scientist nation opportunity.
## 2 Ago current practice nation determine operation speak according.
## 3 Democratic shake bill here grow gas enough analysis least by two.
## 4 Officer relate animal direction eye bag do.
## 5 Class great prove reduce raise author play move each left establish understand read detail.
## 6 Source husband at tree note responsibility defense.
any(is.na(crocodile_species))
## [1] FALSE
# Use==>> colnames(crocodile_species) <- gsub("\\.", "_", colnames(crocodile_species))
# OR use clean_names(): my favorite function because it replaces both . by _ and uppercase to undercase letters
crocodile_species <- crocodile_species %>%
clean_names()
# Check if all names has been changed accordingly
colnames(crocodile_species)
## [1] "observation_id" "common_name" "scientific_name"
## [4] "family" "genus" "observed_length_m"
## [7] "observed_weight_kg" "age_class" "sex"
## [10] "date_of_observation" "country_region" "habitat_type"
## [13] "conservation_status" "observer_name" "notes"
crocodile_species <- crocodile_species %>%
mutate(observed_length_m = as.numeric(observed_length_m),
observed_weight_kg = as.numeric(observed_weight_kg))
#Convert Date
crocodile_species <- crocodile_species %>%
mutate( date_of_observation = as.Date(date_of_observation, format("%d-%m-%y")))
# Check the changes
head(crocodile_species)
## observation_id common_name scientific_name
## 1 1 Morelet's Crocodile Crocodylus moreletii
## 2 2 American Crocodile Crocodylus acutus
## 3 3 Orinoco Crocodile Crocodylus intermedius
## 4 4 Morelet's Crocodile Crocodylus moreletii
## 5 5 Mugger Crocodile (Marsh Crocodile) Crocodylus palustris
## 6 6 Mugger Crocodile (Marsh Crocodile) Crocodylus palustris
## family genus observed_length_m observed_weight_kg age_class
## 1 Crocodylidae Crocodylus 1.90 62.0 Adult
## 2 Crocodylidae Crocodylus 4.09 334.5 Adult
## 3 Crocodylidae Crocodylus 1.08 118.2 Juvenile
## 4 Crocodylidae Crocodylus 2.42 90.4 Adult
## 5 Crocodylidae Crocodylus 3.75 269.4 Adult
## 6 Crocodylidae Crocodylus 2.64 137.4 Adult
## sex date_of_observation country_region habitat_type
## 1 Male 2020-03-31 Belize Swamps
## 2 Male 2020-01-28 Venezuela Mangroves
## 3 Unknown 2020-12-07 Venezuela Flooded Savannas
## 4 Male 2020-11-01 Mexico Rivers
## 5 Unknown 2020-07-15 India Rivers
## 6 Male 2020-06-08 India Reservoirs
## conservation_status observer_name
## 1 Least Concern Allison Hill
## 2 Vulnerable Brandon Hall
## 3 Critically Endangered Melissa Peterson
## 4 Least Concern Edward Fuller
## 5 Vulnerable Donald Reid
## 6 Vulnerable Randy Brown
## notes
## 1 Cause bill scientist nation opportunity.
## 2 Ago current practice nation determine operation speak according.
## 3 Democratic shake bill here grow gas enough analysis least by two.
## 4 Officer relate animal direction eye bag do.
## 5 Class great prove reduce raise author play move each left establish understand read detail.
## 6 Source husband at tree note responsibility defense.
# 📦Load necessary libraries for visualization
library(dplyr)
library(rnaturalearth)
library(rnaturalearthdata)
##
## Attaching package: 'rnaturalearthdata'
## The following object is masked from 'package:rnaturalearth':
##
## countries110
library(sf)
## Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1; sf_use_s2() is TRUE
library(ggplot2)
library(stringr)
#Remove the word "crocodile" from common_name (case insensitive)
#Count how many times each species appears per country (n = n()).
#.groups = "drop" ungroups the result after summarizing.
#Regroup by country only to find the top species per country.
#slice_max(order_by = n, n = 1)
#Within each country, pick the species with the highest count (n).
top_species <- crocodile_species %>%
group_by(country_region, common_name) %>%
summarize(n = n(), .groups = "drop") %>%
group_by(country_region) %>%
slice_max(order_by = n, n = 1) %>%
mutate(common_name = str_replace_all(common_name, regex("crocodile", ignore_case = TRUE), "") %>%
str_trim())
## Load world map data
world <- ne_countries(scale = "medium", returnclass = "sf")
# Join top species data with world map
map_data <- left_join(world, top_species, by = c("name" = "country_region"))
# Plot the map
ggplot(map_data) +
geom_sf(aes(fill = common_name), color = " white ") +
labs(title = "Most Observed Crocodile Species by Country of Origin", fill = "") +
theme_minimal() +
theme(legend.position = "bottom")
### Libraries explanations - dplyr: for data manipulation (grouping,
summarizing, filtering). - rnaturalearth & rnaturalearthdata: to
load Natural Earth world map data. - sf: for handling spatial (map) data
using simple features. - ggplot2: for plotting. - stringr: for
string/text manipulation (used to remove “crocodile” from common
names).
library(ggplot2)
ggplot(top_species, aes(x = reorder(common_name, n), y = n)) +
geom_col(fill = " darkcyan ", color = " black ") +
coord_flip() +
labs(title = "Top Most Observed Species", x = "Species", y = "Count") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
## 4.1.3. Age Class Distribution
ggplot(crocodile_species, aes(x = age_class)) +
geom_bar(fill = " darkcyan ", color = " black ") +
labs(title = "Age Class Distribution", x = "age class", y = "count") +
theme_minimal()
ggplot(crocodile_species, aes(x = sex)) +
geom_bar(fill = " darkcyan ", color = " black ") +
labs(title = "Sex Distribution", x = "sex", y = "count")
ggplot(crocodile_species, aes(x = habitat_type)) +
geom_bar(fill = " darkcyan ", color = " black ") +
labs(title = "Habitat Type Distribution", x = "habitat type", y = "count") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
ggplot(crocodile_species, aes(x = conservation_status)) +
geom_bar(fill = " darkcyan ", color = " black ") +
labs(title = "Conservation Status", x = "conservation status", y = "count")+
theme(axis.text.x = element_text(angle = 45, hjust = 1))
ggplot(crocodile_species, aes(x = observed_length_m)) +
geom_histogram(fill = " darkcyan ", bins = 20, color = " black ") +
labs(title = "Distribution of Length Observation (m)", x = "length observed (m)" , y = "frequency")
ggplot(crocodile_species, aes(x = observed_weight_kg)) +
geom_histogram(fill = " darkcyan ", bins = 20, color = " black ")+
labs(title = "Distribution of weight observed (kg)", x = "weight observed (kg)", y ="frequency")
ggplot(crocodile_species, aes(x = observed_length_m, y = observed_weight_kg)) +
geom_point(alpha = 0.6, color = " darkcyan ") +
geom_smooth(method = "lm", se = FALSE, color = " red ") +
labs(title = "Observed Length vs Weight", x = "Length (m)", y = "Weight (kg)")
## `geom_smooth()` using formula = 'y ~ x'
ggplot(crocodile_species, aes(x = reorder(age_class, observed_weight_kg, median), y = observed_weight_kg, fill = age_class)) +
geom_boxplot() +
labs(title = "Crocodile Weight By Age Class (Ascending Order)", x = "Age Class", y = "Weight (kg)") +
theme_minimal() +
theme(legend.position = "right")
ggplot(crocodile_species, aes(x = sex,y = observed_length_m, fill = sex)) +
geom_boxplot() +
labs(title = "Crocodile Length by Sex", x = "Sex", y = "Length (m)") +
theme_minimal() +
theme(legend.position = "none")
ggplot(crocodile_species, aes(x = date_of_observation)) +
geom_histogram(fill = " darkcyan ", binwidth = 30, color = " black ") +
labs(title = "Number of Crocodile Observation Overtime", x = "date", y = "count")
##sorts the habitats by total number of observations (highest to lowest)
ggplot(crocodile_species, aes(x = reorder(habitat_type, -table(habitat_type)[habitat_type]), fill = conservation_status)) +
geom_bar(position = "stack") +
labs(title = "Habitat Type vs Conservation Type", x = "habitat", y = "count") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
##orders from most frequent to least frequent.
ggplot(crocodile_species, aes(x = reorder(age_class, -table(age_class)[age_class]), fill = sex)) +
geom_bar(position = "dodge") +
labs(title = "Age Class vs Sex", x = "age class", y = "count")
## END