Asteroids are abundant bodies in our solar system, and our planet is no stranger to collisions with these bodies. The effect of these collisions can range from negligible to cataclismic for life on earth. The document presents an interactive map built with leaflet that shows the confirmed asteroid impacts in the continental US.

Let’s begin by loading the required packages for this task.

library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(leaflet)
## Warning: package 'leaflet' was built under R version 4.3.2
library(readr)

Now, lets load our data. For this assignment, we are using the ‘North America Impact Structures’ data frame from the ‘Earth Impact Database’. More information can be found here.

First, lets load our data frame and store it in the variable ‘impacts’.

impacts <- read_csv("impacts.csv")
## Rows: 62 Columns: 10
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (10): Crater Name, Location, Latitude, Longitude, Diameter (km), Age (Ma...
## 
## ℹ 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.

Let’s take a quick look at what we’re working with.

head(impacts)
## # A tibble: 6 × 10
##   `Crater Name` Location  Latitude Longitude `Diameter (km)` `Age (Ma)*` Exposed
##   <chr>         <chr>     <chr>    <chr>     <chr>           <chr>       <chr>  
## 1 Ames          Oklahoma… N 36° 1… W 98° 12' 16              470 ± 30    N      
## 2 Avak          Alaska, … N 71° 1… W 156° 3… 12              Mar-95      N      
## 3 Barringer     Arizona,… N 35° 2' W 111° 1' 1.18            0.049 ± 0.… Y      
## 4 Beaverhead    Montana,… N 44° 3… W 113° 0' 60              ~ 600       Y      
## 5 Brent         Ontario,… N 46° 5' W 78° 29' 3.8             452.8 ± 2.7 N      
## 6 Calvin        Michigan… N 41° 5… W 85° 57' 8.5             450 ± 10    N      
## # ℹ 3 more variables: Drilled <chr>, `Target Rock**` <chr>,
## #   `Bolide Type***` <chr>

As we can see, the data frame contains information on impacts not only in the US. This is expected as the data frame is a list of confirmed impacts in all of North America. To continue with our objective, lets filter out all of the non-US impacts from the list. Lets call unique() on the ‘location’ variable to see the way they name the US.

unique(impacts$Location)
##  [1] "Oklahoma, U.S.A."               "Alaska, U.S.A."                
##  [3] "Arizona, U.S.A."                "Montana, U.S.A."               
##  [5] "Ontario, Canada"                "Michigan, USA"                 
##  [7] "Saskatchewan, Canada"           "Quebec, Canada"                
##  [9] "Virginia, U.S.A."               "Yucatan, Mexico"               
## [11] "Wyoming, USA"                   "Missouri, U.S.A."              
## [13] "Iowa, U.S.A."                   "Illinois, U.S.A."              
## [15] "Wyoming, U.S.A."                "Alberta, Canada"               
## [17] "Tennessee, U.S.A."              "Wisconsin, U.S.A."             
## [19] "Nunavut, Canada"                "Kansas, U.S.A."                
## [21] "Indiana, U.S.A."                "Texas, U.S.A."                 
## [23] "Kentucky, U.S.A."               "Newfoundland/Labrador, Canada" 
## [25] "Nova Scotia, Canada"            "North Dakota, U.S.A."          
## [27] "NWT, Canada"                    "Manitoba, Canada"              
## [29] "New Mexico , U.S.A."            "Ohio, U.S.A."                  
## [31] "Victoria Island, Arctic Canada" "Utah, U.S.A."                  
## [33] "Alabama, U.S.A."                "Alberta, Canada "

As we can see, the US is referred to as either ‘U.S.A.’ or ‘USA’. Let’s use this information to filter our list.

indices <- grep("U.S.A.|USA", impacts$Location)
USA_impacts <- impacts[indices, ]

Great, now let’s take a look at the latitude vector from our resulting data frame;

USA_impacts$Latitude
##  [1] "N 36° 15'" "N 71° 15'" "N 35° 2'"  "N 44° 36'" "N 41° 50'" "N 37° 17'"
##  [7] "N 43° 7'"  "N 37° 50'" "N 37° 54'" "N 43° 19'" "N 42° 3'"  "N 42° 40'"
## [13] "N 36° 17'" "N 40° 36'" "N 43° 58'" "N 37° 35'" "N 40° 45'" "N 42° 35'"
## [19] "N 31° 17'" "N 36° 37'" "N 48° 58'" "N 31° 45'" "N 47° 36'" "N 44° 43'"
## [25] "N 35° 45'" "N 39° 2'"  "N 30° 36'" "N 38° 26'" "N 36° 23'" "N 32° 31'"

As we can see, the latitude is given in degrees and minutes format. We need to convert them into decimal before feeding it into addMarkers(). Let’s do that now for both ‘Latitude’ and ‘Longitude’.

latitudes <- USA_impacts$Latitude
latitudes_cleaned <- gsub("N ", "", gsub("'", "", latitudes))
latitudes_split <- strsplit(latitudes_cleaned, "°")
latitudes_decimal <- sapply(latitudes_split, function(x) {
    degrees <- as.numeric(x[1])
    minutes <- as.numeric(x[2])
    degrees + minutes / 60
})

longitudes <- USA_impacts$Longitude
longitudes_cleaned <- gsub("W ", "-", gsub("'", "", longitudes))
longitudes_split <- strsplit(longitudes_cleaned, "°")
longitudes_decimal <- sapply(longitudes_split, function(x) {
    degrees <- as.numeric(x[1])
    minutes <- as.numeric(x[2])
    degrees + minutes / 60
})

Let’s now create the map and add the markers with the vectors we’ve defined.

impacts_map <- leaflet() %>% 
      addTiles() %>%
      addMarkers(lat = latitudes_decimal, lng = longitudes_decimal)
impacts_map

We can now see a map with all the confirmed asteroid impactes in the continental USA! Thank you for reading and have a great day!