Introduction

This report provides an exploratory analysis of the global crocodile species dataset. It includes data loading, summary statistics, and visualizations.

Overall Insights

##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

1. Load World Crocodile Species Dataset

crocodile_species <- read.csv("crocodile_dataset.csv")

2. Dataset Overview: Glimpes of the Data, Column names and overall summary

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.

3. Data Cleaning

3.1. Check if there are any NAs at all

any(is.na(crocodile_species))
## [1] FALSE

3.2. Replace all dots with underscores in column names and Check if all names has been chenged

# 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"

3.3. Change/Convert char columns into numeric columns

crocodile_species <- crocodile_species %>% 
  mutate(observed_length_m = as.numeric(observed_length_m), 
         observed_weight_kg = as.numeric(observed_weight_kg))

3.4. Change/Convert Date order from DD-MM-YYY to YYY-MM-DD standard

#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.

4. Data Visualization

4.1. Categorical Distributions Analysis

4.1.1. Most Observed Crocodile Species by Country of it’s origin

# 📦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).

4.1.2. Common Name distribution (top 10 species)

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()

4.1.4. Sex Distribution

ggplot(crocodile_species, aes(x = sex)) +
  geom_bar(fill = " darkcyan ", color = " black ") +
  labs(title = "Sex Distribution", x = "sex", y = "count")

4.1.5. Habitat type distribution

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))

4.1.6. Conservation status

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))

5.2. Quantitative Distributions Analysis

5.2.1. Length distribution

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")

5.2.2. Weight distribution

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")

5.2.3. Length vs Weight Analysis

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'

5.2.4. Crocodiles Weight by Age Class

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")

5.2.4. Crocodile Length by sex

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")

5.3. Temporal Analysis

5.3.1 Crocodile Species Observations over time

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")

5.3.2. Relationships Between Categorical Variables

##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))

5.3.3. Crocodile Age Class vs Sex

##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