Thank you EARL 2026
8th October, I gave a light-hearted lighting talk titled “let’s hunt alien” EARL 2026, in Brighton! For those of you who was with us and enjoyed by talk, a big thank you! I’m overwhelmed by your reactions. And thank you to Data Cove team, specfically Laura who has given me so much encouragement.
The talk is based on my blog back in Jun 2024 , so most of the code will be there!
Side note, I wanted this talk to be a almost a scifi movie watching experience so I styled the last slide like a movie credit scene.
Additional Code
Most code will be in my original code blog back in Jun 2024 . The only other code missing here is clustering and wrangling.
Load relevant datas
library (dplyr)
library (dbplyr)
library (ggplot2)
library (duckdb)
## So the only way is to laod that data from geometry
conn <- DBI:: dbConnect (duckdb:: duckdb ("ufo.db" ,read_only = TRUE ))
ufo_data = conn |>
tbl ("analysis.ufo_observe_by_state_year" )
us_counties = conn |>
tbl (sql ("select * exclude geometry, st_asWkB(geometry) as geometry from clean.us_state_polygon" ))
us_count_full_name_ = conn |>
tbl (sql ("from clean.us_population" )) |>
group_by (county_id) |>
slice_max (n= 1 ,order_by= api_year) |>
select (county_id,fullname= GEONAME) |>
collect () |>
# this is to make the name in a printable format for visualise on specific state
mutate (
full_name= stringr:: str_extract (fullname, "[ \\ w \\ s]+,[ \\ w \\ s]+" ) |>
stringr:: str_replace (", \\ s" ," \n " )
) |>
collect ()
mart = ufo_data |>
left_join (us_counties, "county_id" ) |>
mutate (year = as.integer (year))
class (mart) <- c ("ufo_mart" ,class (mart))
My favourite way of doing this in R is to create a S3 class for different dataframe.
Functions To Help with Aggregation & Graphics
agg.ufo_mart = function (df) {
df |>
summarise (
ufo_count = sum (ufo_count),
ufo_multi_observe = sum (ufo_multi_observe),
geometry = first (geometry),
density = mean (as.numeric (DENSITY), na.rm= TRUE ),
population = mean (as.numeric (POP))
) |>
mutate (
ufo_count_density = (ufo_count / density),
ufo_multiserve_density = (ufo_multi_observe / density)
)
}
collect_sf.ufo_mart = function (df) {
x = df |>
collect () |>
mutate (
geometry= sf:: st_as_sfc (geometry, crs= 4269 )
) |>
sf:: st_as_sf ()
class (x) <- c ("ufo_mart" , class (x))
return (x)
}
vis.ufo_mart = function (df, variable, ..., title) {
df |>
tmap:: tm_shape () +
tmap:: tm_polygons (
fill = variable,
fill.scale = tmap:: tm_scale_continuous_pseudo_log (
...
),
fill.legend = tmap:: tm_legend (position= c ("right" ,"bottom" ),title= title),
) +
tmap:: tm_layout (legend.outside= TRUE )
}
as_ufo_mart= function (x) {
if (inherits (x, "ufo_mart" )) {
return (x)
} else {
class (x) <- c ("ufo_mart" , class (c))
return (x)
}
}
vis = function (...) {UseMethod ("vis" )}
collect_sf = function (...) {UseMethod ("collect_sf" )}
agg = function (...) {UseMethod ("agg" )}
mutate.ufo_mart = function (...){
as_ufo_mart (NextMethod ("mutate" ))
}
vis_top_score = function (...) {UseMethod ("vis_top_score" )}
vis_top_score.ufo_mart = function (x,
variable,top_n,desc= TRUE ,
label_from = "full_name" ,
colorpalette = "brewer.bu_pu" ,
text_size= 0.7 ,
limits= c ()
) {
variable = enquo (variable)
var_label = as_label (variable)
if (length (limits) == 0 ) {
limits = pull (x, {{variable}}) |> range ()
}
x= x |>
arrange ({{variable}} |> desc ())
if (desc) {
x = x |> slice_head (n= top_n)
} else {
x = x |> slice_tail (n= top_n)
}
mid_point = pull (x, {{variable}}) |> median ()
label_glue = glue:: glue ("{{{label_from}}}" )
x |>
# transform
mutate (
"{var_label}" : = round (!! variable,2 ),
text_color= ifelse ({{variable}} > mid_point, "white" , "black" ),
label = glue:: glue (label_glue)
) |>
sf:: st_as_sf () |>
tmap:: tm_shape () +
tmap:: tm_polygons (
fill= var_label,
fill.scale = tmap:: tm_scale_continuous_log (values= colorpalette),
fill.legend = tmap:: tm_legend_hide (),
fill_alpha= 0.5 ,
limits= limits
) +
tmap:: tm_text (
text= "label" ,
col= "text_color" ,
size= text_size
)
}
Function wraper for spdep local moran
# Local Moran Statistics -----------------------
local_moran_c = function (variable, nb, get = c ("Ii" ,"E.Ii" ,"Var.Ii" ,"Pr(z > E(Ii))" )) {
lw = spdep:: nb2listw (nb, style= "W" ,zero.policy = TRUE )
t = spdep:: localmoran_perm ( {{variable}}, lw, alternative= "greater" )
t[,get]
}
local_moran_c_quadr= function (variable, nb, get = c ("Ii" ,"E.Ii" ,"Var.Ii" ,"Pr(z > E(Ii))" )) {
lw = spdep:: nb2listw (nb, style= "W" ,zero.policy = TRUE )
t = spdep:: localmoran_perm ( {{variable}}, lw, alternative= "greater" )
attributes (t)$ quadr$ mean
}
# some interesting event data
dot_area_51 = sf:: st_point (c (- 115.80833 ,37.23333 )) |>
sf:: st_sfc (crs= 4326 )
dot_massachuesetts_bay = sf:: st_point (c (- 71.05 ,42.36 )) |>
sf:: st_sfc (crs= 4326 )
ufo_state_summary_since_xxxx = mart |>
filter (year > 1890 ) |>
group_by (county_id) |>
agg () |>
collect_sf ()
nb= spdep:: poly2nb (ufo_state_summary_since_xxxx, queen= TRUE )
ufo_state_summary_since_xxxx = ufo_state_summary_since_xxxx |>
mutate (
ufo_density_moran_p = local_moran_c (ufo_count_density,nb, "Pr(z > E(Ii))" ),
ufo_density_moran_i = local_moran_c (ufo_count_density,nb,"Ii" ),
ufo_density_lisa = local_moran_c_quadr (ufo_count_density,nb)
) |>
left_join (tibble:: as_tibble (us_count_full_name_) |> select (county_id, full_name) )
Local Moran’s I Map
ufo_state_summary_since_xxxx |>
ggplot () +
geom_sf (
aes (geometry= geometry, fill= ufo_density_lisa)
) +
scale_fill_viridis_d (option = "F" ) +
theme_minimal () +
theme (
plot.title = ggtext:: element_markdown (),
plot.subtitle = ggtext:: element_markdown (),
plot.caption = ggtext:: element_markdown ()
) +
labs (
title= "<span style='font-weight: bold'>Alien have a thing for Cowboys</span>" ,
subtitle= "Spatial auto-correlation is stronger in <span style='color: #D35400 font-weight: bold'> Western states </span> than in the <span style='color: #7C0969'>Eastern states</span>" ,
caption= "Using local moran statistic"
)
UFO Sighting Absorbed Population Density
conn |> DBI:: dbExecute ("load spatial;" )
ufo_points = conn |>
tbl (sql ("select * from clean.ufo_data_standardized" )) |>
collect () |>
mutate (
geometry = sf:: st_as_sfc (geometry,crs= 'EPSG:4269' )
) |>
sf:: st_as_sf ()
Observation Heatmap with annotation
ℹ tmap modes "plot" - "view"
ℹ toggle with `tmap::ttm()`
Observation Heatmap with annotation
.area_51_label.col = "black"
.area_51_label.fill = "#F5B027"
.ufo_dot_color= "#28B463"
.moran_color_fill = "magma"
## scatter plot mini map ---------------------
top_x_county = ufo_state_summary_since_xxxx |>
# left_join(us_count_full_name_, by="county_id") |>
arrange (ufo_density_moran_i |> desc ()) |>
mutate (label = full_name) |>
head (2 )
m_top_x_county_outline = top_x_county |>
sf:: st_as_sf () |>
tmap:: tm_shape () +
tmap:: tm_basemap () +
tmap:: tm_polygons () +
tmap:: tm_text (
text= "label" ,
col= "white" ,
size= 0.5
)
m_ufo_points = ufo_points |>
inner_join (select (tibble:: as_tibble (top_x_county), county_id), by= "county_id" ) |>
tmap:: tm_shape () +
tmap:: tm_symbols (
shape = tmap:: tmap_icons ("asset/ufo.png" ),
size= 0.3
)
m_area_51= tmap:: tm_shape (dot_area_51) +
tmap:: tm_symbols (
shape= tmap:: tmap_icons ("asset/Area-51-UFO-Sign.png" ),
)
## Another minimap for visualise first UFO sighting event
m_mass_bay = tmap:: tm_shape (dot_massachuesetts_bay) +
tmap:: tm_symbols (
shape = tmap:: tmap_icons ("asset/alien-abduction.png" )
)
## big choro plot mini map ---------------------
# tmap::tmap_mode("plot")
ufo_state_summary_since_xxxx |>
tmap:: tm_shape () +
tmap:: tm_basemap () +
tmap:: tm_polygons (
id = "county_id" ,
fill = "ufo_count_density" ,
fill.scale = tmap:: tm_scale_continuous_pseudo_log (
values= .moran_color_fill,
),
fill.legend = tmap:: tm_legend_hide ()
) +
tmap:: tm_layout (legend.outside= TRUE ) +
m_area_51 +
tmap:: tm_text (
text= "51" ,
col= "white" ,
size = 0.7
) +
m_mass_bay
UFO Sighting without Absorbed Population Density
Raw UFO count without anything
ℹ tmap modes "plot" - "view"
Raw UFO count without anything
top_count = ufo_state_summary_since_xxxx |>
slice_max (ufo_count) |>
mutate (text = glue:: glue ("
{round(ufo_count)} Alien Sighting
in {full_name}
" )) |>
tmap:: tm_shape () +
tmap:: tm_polygons (fill= "midnightblue" ) +
tmap:: tm_text (text= "text" ,col= "white" )
ufo_state_summary_since_xxxx |>
tmap:: tm_shape () +
tmap:: tm_basemap () +
tmap:: tm_polygons (
fill = "ufo_count" ,
fill.scale = tmap:: tm_scale_continuous_pseudo_log (
values= 'cividis' ,
),
fill.legend = tmap:: tm_legend_hide ()
) +
m_area_51 +
m_mass_bay +
# tmap::tm_inset(top_count,group_id = "1",height=20, width = 20, position = c("right","bottom")) +
# tmap::tm_components(group_id = "1", position = c("bottom","left")) +
tmap:: tm_layout (
legend.outside= TRUE ,
outer.margins = rep (0 ,4 ),
inner.margins = rep (0.09 ,4 )
) +
tmap:: tm_title ("Raw UFO Event count" )