earthquakes_2025

Author

Christopher Hamatto

Surface rupture caused by an earthquake

Image source: U.S. Geological Survey, “Surface Rupture from Fault”.

Introduction

I picked earthquakes because I wanted to see where the stronger ones happened and how deep they were. I found the data using the USGS Earthquake Catalog. I searched for worldwide earthquakes from 2025 with magnitudes of 6 or higher and downloaded the results as a CSV. The file had 145 rows and 22 columns. I used dplyr to keep earthquakes with magnitudes of 6 or higher and selected six variables: latitude, longitude, depth, magnitude, magnitude type, and network. Latitude, longitude, depth, and magnitude are quantitative variables. Magnitude type and network are categorical variables. I plan to compare the earthquakes’ locations and depths with their magnitudes. The filter kept all 145 rows because the downloaded CSV already matched the magnitude rule.

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.2.1     ✔ readr     2.2.0
✔ forcats   1.0.1     ✔ stringr   1.6.0
✔ ggplot2   4.0.3     ✔ tibble    3.3.1
✔ lubridate 1.9.5     ✔ tidyr     1.3.2
✔ purrr     1.2.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
# Load the earthquake data
earthquakes <- readr::read_csv("earthquakes_2025.csv")
Rows: 145 Columns: 22
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr   (8): magType, net, id, place, type, status, locationSource, magSource
dbl  (12): latitude, longitude, depth, mag, nst, gap, dmin, rms, horizontalE...
dttm  (2): time, updated

ℹ 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.
head(earthquakes)
# A tibble: 6 × 22
  time                latitude longitude depth   mag magType   nst   gap  dmin
  <dttm>                 <dbl>     <dbl> <dbl> <dbl> <chr>   <dbl> <dbl> <dbl>
1 2025-12-31 14:26:57    40.1      143.     27   6   mww       242    29 1.58 
2 2025-12-28 02:51:49    -8.98     -79.0    58   6.2 mww       112    40 3.68 
3 2025-12-27 15:05:55    24.7      122.     63   6.6 mww       298     9 0.568
4 2025-12-24 09:47:06    22.9      121.      8   6   mww       212    47 0.176
5 2025-12-22 10:31:27    -5.70     146.    107   6.5 mww       129    14 4.01 
6 2025-12-12 02:44:12    40.9      143.     19   6.7 mww       119    39 1.15 
# ℹ 13 more variables: rms <dbl>, net <chr>, id <chr>, updated <dttm>,
#   place <chr>, type <chr>, horizontalError <dbl>, depthError <dbl>,
#   magError <dbl>, magNst <dbl>, status <chr>, locationSource <chr>,
#   magSource <chr>
# Check the column names and dataset size
names(earthquakes)
 [1] "time"            "latitude"        "longitude"       "depth"          
 [5] "mag"             "magType"         "nst"             "gap"            
 [9] "dmin"            "rms"             "net"             "id"             
[13] "updated"         "place"           "type"            "horizontalError"
[17] "depthError"      "magError"        "magNst"          "status"         
[21] "locationSource"  "magSource"      
dim(earthquakes)
[1] 145  22
# Count the categories in status and magnitude type
table(earthquakes$status)

reviewed 
     145 
table(earthquakes$magType)

 mb mwb mww 
  6   2 137 
table(earthquakes$type)

earthquake 
       145 
table(earthquakes$net)

 ak  us 
  1 144 
# Summarize the quantitative variables
summary(earthquakes$mag)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   6.00    6.00    6.20    6.39    6.60    8.80 
summary(earthquakes$depth)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  5.639  10.000  19.000  38.584  39.000 553.000 
summary(earthquakes$latitude)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
-60.979 -12.376   9.867  10.568  49.373  71.176 
summary(earthquakes$longitude)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
-178.54  -59.56  126.69   63.91  157.73  178.86 
# Plot earthquake magnitude by depth
ggplot(data = earthquakes, mapping = aes(x = depth, y = mag)) +
  geom_point()

# Count earthquakes by magnitude type and network
ggplot(data = earthquakes, mapping = aes(x = magType, fill = net)) +
  geom_bar()

# Keep earthquakes with magnitude 6 or higher and select project variables
earthquakes_clean <- earthquakes %>%
  filter(mag >= 6) %>%
  select(latitude, longitude, depth, mag, magType, net)

dim(earthquakes_clean)
[1] 145   6

I used magnitude as the response variable because it measures earthquake strength. I used depth, latitude, and longitude as predictors because they describe how deep an earthquake was and where it happened.

# Model magnitude using depth and location
earthquake_model <- lm(mag ~ depth + latitude + longitude, data = earthquakes_clean)
summary(earthquake_model)

Call:
lm(formula = mag ~ depth + latitude + longitude, data = earthquakes_clean)

Residuals:
    Min      1Q  Median      3Q     Max 
-0.4171 -0.3710 -0.1898  0.1932  2.4255 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)  6.391e+00  5.317e-02 120.196   <2e-16 ***
depth        1.611e-04  6.479e-04   0.249    0.804    
latitude    -1.786e-04  1.140e-03  -0.157    0.876    
longitude   -8.046e-05  3.608e-04  -0.223    0.824    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 0.48 on 141 degrees of freedom
Multiple R-squared:  0.001335,  Adjusted R-squared:  -0.01991 
F-statistic: 0.06285 on 3 and 141 DF,  p-value: 0.9793

The model equation is: mag = 6.391 + 0.0001611(depth) − 0.0001786(latitude) − 0.00008046(longitude).

The adjusted R-squared is -0.01991, which means the model explains almost none of the differences in earthquake magnitude. The overall p-value is 0.9793, and each predictor’s p-value is above 0.05. In this dataset, depth, latitude, and longitude were not significant predictors of magnitude.

library(maps)

Attaching package: 'maps'
The following object is masked from 'package:purrr':

    map
# Load packages for data work and the world map
library(tidyverse)
library(maps) 
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
# Map earthquake locations by magnitude type
world_map <- map_data("world")

ggplot() +
  geom_polygon(data = world_map,
               aes(x = long, y = lat, group = group),
               fill = "gray95", color = "white") +
  geom_point(data = earthquakes_clean,
             aes(x = longitude, y = latitude,
                 color = magType, size = mag),
             alpha = 0.7) +
  scale_color_brewer(palette = "Set1") +
  coord_quickmap() +
  labs(title = "Global Earthquakes M6+ (2025)",
       subtitle = "Size shows magnitude; color shows magnitude type",
       x = "Longitude", y = "Latitude",
       color = "Magnitude type", size = "Magnitude",
       caption = "Source: U.S. Geological Survey Earthquake Catalog") +
  theme_minimal() +
  theme(legend.position = "bottom", legend.box = "vertical")

library(plotly)
# Create an interactive plot of earthquake depth and magnitude
depth_plot <- ggplot(data = earthquakes_clean,
                     mapping = aes(x = depth, y = mag, color = magType)) +
  geom_point(alpha = 0.7) +
  scale_color_brewer(palette = "Set1") +
  labs(title = "Magnitude and Depth of Major Earthquakes",
       subtitle = "Hover over a point to see its values",
       x = "Depth (km)", y = "Magnitude",
       color = "Magnitude type",
       caption = "Source: U.S. Geological Survey Earthquake Catalog") +
  theme_minimal()

ggplotly(depth_plot)

This v map shows where the 145 earthquakes with a magnitude of 6 or higher happened in 2025. Many were around the Pacific Ocean, and most used the mww magnitude type. The scatter plot shows that most earthquakes were shallow. The deepest ones were not necessarily the strongest, which matches my regression results. I would have liked to show how the earthquakes changed over time, but I focused on their locations, depths, and magnitudes.

References

  • U.S. Geological Survey. Earthquake Catalog: 2025 earthquakes, magnitude 6.0 or higher. CSV dataset

  • U.S. Geological Survey. Surface Rupture from Fault [Image]. Source page

  • OpenAI. (2026). ChatGPT [Large language model]. https://chatgpt.com/. Used for help with R code and project explanations.