#######################################################################################################################
### WEEK 1 ############################################################################################################
#######################################################################################################################
## function: handle_negative_dates ---------------------------------------------
#' Handling negative dates (BC dates)
#'
#' \code{handle_negative_dates} takes negative dates
#'
#' @param y The year as a nummeric input
#' @param m The month as a nummeric input
#' @param d the day as a numeric input
#'
#' @return Date as a date class, and which is negative
#'
#' @examples
#' handle_negative_dates(-100, 1, 1)
#'
#' @export
#'
handle_negative_dates <- function(y, m, d) {
origin_date <- base::as.numeric(as.Date("0 1 1", "%Y %m %d", origin = "1970-01-01"))
mirror_date <- base::as.Date(paste(-y-1, 13-m, abs(27-d)+1, sep = '-'), '%Y-%m-%d', origin = '1970-01-01') # -y -1 (?) # abs(27-d)+1
mirror_date_num <- base::as.numeric(mirror_date)
delta <- origin_date - mirror_date_num
days_gone_by <- delta + origin_date
date_new <- base::as.Date(days_gone_by, origin = "1970-01-01")
return(date_new)
}
## function: handle_positive_dates ---------------------------------------------
#' Handling positive dates (BC dates)
#'
#' \code{handle_positive_dates} takes positive dates
#'
#' This function takes a positive date via an input of
#' year, month and day (seperately) and gives back the date
#' as a date class. very simple function.
#'
#' @param y The year as a nummeric input
#' @param m The month as a nummeric input
#' @param d the day as a numeric input
#'
#' @return Date as a date class, and which is positive
#'
#' @examples
#' handle_positive_dates(2010, 10, 10)
#'
#' @export
#'
handle_positive_dates <- function(y, m, d) {
date_paste <- base::paste0(y, "-", m, "-", d)
date_new <- base::as.Date(date_paste, format = "%Y-%m-%d")
base::return(date_new)
} # END function handle_positive_dates
## function: eq_location_clean() ---------------------------------------------
#' Cleans the variable "LOCATION_NAME"
#'
#' \code{eq_location_clean} strips down from the LOCATION_NAME variable the
#' country. The function input is the whole earth quake data, of which it then
#' mutates the LOCATION_NAME.
#'
#' @param data A data frame of NOAA significant earthquake data
#'
#' @importFrom magrittr "%>%"
#' @importFrom purrr map2_chr
#' @importFrom stringr str_trim
#' @importFrom stringr str_to_title
#' @importFrom dplyr mutate
#'
#' @return it returns the data frame back, but with the mutated LOCATION_NAME
#'
#' @export
#'
eq_location_clean <- function(data){
data <- data %>%
dplyr::mutate(
LOCATION_NAME = purrr::map2_chr(COUNTRY, LOCATION_NAME,
function(COUNTRY, LOCATION_NAME) {gsub(paste0(COUNTRY, ":"),"",LOCATION_NAME)}),
LOCATION_NAME = stringr::str_trim(LOCATION_NAME),
LOCATION_NAME = stringr::str_to_title(LOCATION_NAME)
)
}
## function: eq_clean_data() ---------------------------------------------
#' Loads and Cleans the Earth Quake data
#'
#' \code{eq_clean_data} loads the data, cleans the data (including the LOCATION_NAME variable)
#' and gives back the data frame. There is no input to this function
#'
#' @importFrom magrittr "%>%"
#' @importFrom readr read_tsv
#' @importFrom dplyr mutate
#'
#' @return it returns the data frame, cleaned and with correct dates (with date class)
#'
#' @export
eq_clean_data <- function() {
data("NOAAearthquakesRAW")
data <- NOAAearthquakesRAW %>%
dplyr::mutate(MONTH = base::replace(MONTH, base::which(base::is.na(MONTH)), 1)) %>%
dplyr::mutate(DAY = base::replace(DAY, base::which(base::is.na(DAY)), 1)) %>%
dplyr::mutate(date = base::ifelse(YEAR < 0,
handle_negative_dates(YEAR, MONTH, DAY),
handle_positive_dates(YEAR, MONTH, DAY)
)) %>%
dplyr::mutate(date = base::as.Date(date, origin = "1970-01-01")) %>%
dplyr::mutate(LATITUDE = base::as.numeric(LATITUDE)) %>%
dplyr::mutate(LONGITUDE = base::as.numeric(LONGITUDE))
data <- eq_location_clean(data)
}
#######################################################################################################################
### WEEK 2 ############################################################################################################
#######################################################################################################################
## function: geom_timeline (building the layer) --------------------------------
## quite generic
## builds the layer based on the geom specifications
## geom specification is defined in the next function
## next function is:
#' Function which builts the layer for the ggplot.
#'
#' @importFrom ggplot2 layer
#'
#' @param mapping See \code{ggplot2} \code{\link[ggplot2]{layer}}
#' @param data See \code{ggplot2} \code{\link[ggplot2]{layer}}
#' @param stat See \code{ggplot2} \code{\link[ggplot2]{layer}}
#' @param position See \code{ggplot2} \code{\link[ggplot2]{layer}}
#' @param na.rm See \code{ggplot2} \code{\link[ggplot2]{layer}}
#' @param show.legend See \code{ggplot2} \code{\link[ggplot2]{layer}}
#' @param inherit.aes See \code{ggplot2} \code{\link[ggplot2]{layer}}
#' @param ... other arguments passed on to \code{\link[ggplot2]{layer}}
#'
#' @export
geom_timeline <- function(mapping = NULL, data = NULL, stat = "identity",
position = "identity", na.rm = FALSE,
show.legend = NA, inherit.aes = TRUE, ...) {
ggplot2::layer(
geom = geom_timeline_proto_class, # this here is important
mapping = mapping,
data = data, stat = stat, position = position,
show.legend = show.legend, inherit.aes = inherit.aes,
params = list(na.rm = na.rm, ...)
)
}
## function: draw_panel_function ------------------------------------------------
#' @importFrom ggplot2 ggproto
#' @importFrom grid pointsGrob
#' @importFrom grid gpar
#'
#' @param data earth quake data set
#' @param panel_scales I don't know what that is
#' @param coord transformed data set
#'
#' @export
draw_panel_function <- function(data, panel_scales, coord) {
coords <- coord$transform(data, panel_scales)
coords <- coords[!base::is.na(coords$size), ]
# resizing the points
max_size <- base::max(coords$size)
coords$size <- coords$size / max_size * 1.3
grid::pointsGrob(
x = coords$x,
y = coords$y,
pch = coords$shape,
gp = grid::gpar(
col = coords$colour,
alpha = coords$alpha,
cex = coords$size
)
)
}
## function: geom_timeline_proto_class ---------------------------------------------
#' Function creates the new geom (geom_timeline).
#'
#' @format NULL
#' @usage NULL
#'
#' @export
geom_timeline_proto_class <- ggplot2::ggproto("geom_timeline_proto_class", ggplot2::Geom,
required_aes = c("x"),
default_aes = ggplot2::aes(y = 0,
fill = NA,
colour = "grey3",
alpha = 0.4,
shape = 19,
stroke = 0.5,
size = 1
),
draw_key = ggplot2::draw_key_point,
draw_panel = draw_panel_function
)
## function: geom_timeline_label (building the layer) --------------------------------
#' Function which builts the layer for the ggplot
#'
#' @importFrom ggplot2 layer
#'
#' @param mapping See \code{ggplot2} \code{\link[ggplot2]{layer}}
#' @param data See \code{ggplot2} \code{\link[ggplot2]{layer}}
#' @param stat See \code{ggplot2} \code{\link[ggplot2]{layer}}
#' @param position See \code{ggplot2} \code{\link[ggplot2]{layer}}
#' @param na.rm See \code{ggplot2} \code{\link[ggplot2]{layer}}
#' @param show.legend See \code{ggplot2} \code{\link[ggplot2]{layer}}
#' @param inherit.aes See \code{ggplot2} \code{\link[ggplot2]{layer}}
#' @param ... other arguments passed on to \code{\link[ggplot2]{layer}}
#'
#' @export
geom_timeline_label <- function(mapping = NULL, data = NULL, stat = "identity",
position = "identity", na.rm = FALSE,
show.legend = NA, inherit.aes = TRUE, ...) {
ggplot2::layer(
geom = geom_timeline_label_proto_class, # this here is important
mapping = mapping,
data = data, stat = stat, position = position,
show.legend = show.legend, inherit.aes = inherit.aes,
params = list(na.rm = na.rm, ...)
)
}
#' @importFrom ggplot2 ggproto
#' @importFrom grid pointsGrob
#' @importFrom grid gpar
#' @param data earth quake data set
#' @param panel_scales I don't know what that is
#' @param coord transformed data set
#' Make catagory names friendly to ggplot2 (helper funtion)
#'
#' Changes a string so it is enclosed in back-ticks.
#' This can be used to make column names that have spaces (blanks)
#' or non-letter characters acceptable to ggplot2.
#' This version of the function is vectorized with sapply.
#'
#' @param x string to make acceptable to ggplot2
#' @return x string made acceptable to ggplot2
#'
ggname <- function(x) {
if (class(x) != "character") {
return(x)
}
y <- sapply(x, function(s) {
if (!grepl("^`", s)) {
s <- paste("`", s, sep="", collapse="")
}
if (!grepl("`$", s)) {
s <- paste(s, "`", sep="", collapse="")
}
}
)
y
}
## function: draw_panel_function ------------------------------------------------
#' Outsourced function which builts the plot
#'
#' @format NULL
#' @usage NULL
#'
#' @export
draw_panel_function_label <- function(data, panel_scales, coord) {
coords <- coord$transform(data, panel_scales)
n_max <- coords$n_max[1]
data <- data %>%
dplyr::group_by(group) %>%
dplyr::top_n(n_max, magnitude)
# vertical line
data$xend <- data$x
data$yend <- data$y + 0.08
gg_vertical <- ggplot2::GeomSegment$draw_panel(data, panel_scales, coord)
data$fill <- "black"
data$stroke <- 1.6 # point size
gg_point <- ggplot2::GeomPoint$draw_panel(data, panel_scales, coord)
# text
data$y <- data$yend + 0.01
data$angle <- 30
data$fontface <- 11 # fonts
data$lineheight <- 1
data$hjust <- "left"
data$vjust <- "bottom"
data$family <- "sans"
data$size <- 4.5
gg_text <- ggplot2::GeomText$draw_panel(data, panel_scales, coord)
ggname("geom_timeline_label", grid::grobTree(gg_vertical, gg_text, gg_point))
}
## function: geom_timeline_label_proto_class ---------------------------------------------
#' @param required_aes necessary aes inputs for the geom
#' @param default_aes default values
#' @param draw_key function to draw the legend with the associated geom
#' @param draw_panel where the magic is happening
#' @importFrom ggplot2 ggproto
#' @importFrom ggplot2 Geom
#' @importFrom ggplot2 aes
#' @importFrom ggplot2 draw_key_point
#'
#' @export
geom_timeline_label_proto_class <- ggplot2::ggproto("geom_timeline_label_proto_class", ggplot2::Geom,
required_aes = c("x", "label", "magnitude"),
default_aes = ggplot2::aes(y = 0,
n_max = 3,
colour = "grey3",
alpha = NA,
shape = 19,
linetype = 1,
size = 0.3
),
draw_key = ggplot2::draw_key_point,
draw_panel = draw_panel_function_label
)
#######################################################################################################################
### WEEK 3 ############################################################################################################
#######################################################################################################################
#' Visualization of Earth Quakes
#'
#' \code{eq_map} creates a Leaflet map, adds a polygon according to the chosen
#' country and adds the earthquakes as points (size according to magnitude)
#'
#' @param data_filtered A dataframe
#' @param annot_col Which column shall be displayed in the pop-up
#'
#' @importFrom magrittr "%>%"
#' @importFrom dplyr mutate_
#' @importFrom leaflet leaflet addTiles addProviderTiles addPolygons addCircleMarkers
#' @importFrom stringr str_to_title
#'
#' @return this function gives back a leaflet map. It includes various features.
#'
#' @examples
#' require(magrittr)
#' data("NOAAearthquakes")
#'
#' map_ex <- NOAAearthquakes %>%
#' dplyr::filter(COUNTRY == "MEXICO" & lubridate::year(date) >= 2000) %>%
#' eq_map(annot_col = "date")
#' map_ex
#'
#' @export
eq_map <- function(data_filtered, annot_col = "date") {
data(world)
involved_countries <- base::unique(data_filtered$COUNTRY)
data_filtered <- data_filtered %>%
dplyr::mutate_(popup_col = base::as.name(annot_col))
m <- leaflet::leaflet(data_filtered) %>%
leaflet::addTiles() %>%
leaflet::addProviderTiles("OpenMapSurfer.Roads") %>% # OpenTopoMap
leaflet::addPolygons(data = base::subset(world, name %in% stringr::str_to_title(involved_countries)),
weight = 2,
opacity = 0.8,
fillOpacity = 0.3,
fillColor = "red") %>%
leaflet::addCircleMarkers(
lng = ~LONGITUDE,
lat = ~LATITUDE,
radius = ~EQ_PRIMARY^1.4, # 1.4: scale factor; only for visual effects
weight = 3,
color = c('maroon'),
label = ~base::as.character(EQ_PRIMARY),
popup = ~base::as.character(popup_col)
)
m
}
#' Creates Labes for the leaflet map
#' \code{eq_map} creates a string / character combining some information to display
#' in the pop-up
#'
#' @param data This data frame is the whole earth quake data
#'
#' @return this function gives back a vector with character strings
#'
#' @examples
#' require(magrittr)
#' data("NOAAearthquakes")
#'
#' map_example <- NOAAearthquakes %>%
#' dplyr::filter(COUNTRY == "MEXICO" & lubridate::year(date) >= 2000) %>%
#' dplyr::mutate(popup_text = eq_create_label(.)) %>%
#' eq_map(annot_col = "popup_text")
#' map_example
#'
#' @export
eq_create_label <- function(data) {
txt <- base::paste0("<b>Country: </b>", data$COUNTRY, "<br/>",
"<b>Location: </b>", data$LOCATION_NAME, "<br/>",
"<b>Magnitude: </b>", data$EQ_PRIMARY, "<br/>",
"<b>Total Deaths: </b>", data$TOTAL_DEATHS, "<br/>",
"<b>Date: </b>", data$date)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.