#' calc_dots
#'
#' A function which calculates the position of number and position
#' of dots in the final plot for each row of data.
#'
#' credit to Paul Campbell for the function in his blogpost https://www.cultureofinsight.com/blog/2018/05/02/2018-04-08-multivariate-dot-density-maps-in-r-with-sf-ggplot2/
#'
#' @param df the merged df of a shapefile and population data
#' @param col_names a vector of col_names to select from this merged data. If selecting all columns, can leave as NULL
#' @param n_per_dot the number of n people in each category for every dot
#'
#' @author
#' Paul Campbell, Robert Hickman
#' @export
#' @import sf
calc_dots <- function(df, col_names, n_per_dot) {
if(is.null(col_names)) col_names = names(df)
#get the numbers of dots for each observation
num_dots <- as.data.frame(df)
num_dots <- num_dots[which(names(df) %in% col_names)]
#round the numbers generated by the division
#num_dots <- round(num_dots / n_per_dot)
num_dots <- num_dots / n_per_dot
num_dots <- do.call("cbind", lapply(names(num_dots), function(x) {
data <- random_round(unlist(num_dots[x]))
df <- data.frame(data)
names(df) <- x
return(df)
}))
#calculate the position of each dot within the shapefile boundaries
data <- lapply(names(num_dots), function(x) {
dots_df <- sf::st_sample(df, size = unlist(num_dots[x]), type = "random")
dots_df <- sf::st_coordinates(st_cast(dots_df, "POINT"))
dots_df <- as.data.frame(dots_df)
names(dots_df) <- c("lon", "lat")
dots_df$variable = x
return(dots_df)
})
#bind this data together and randomly shuffle
sf_dots <- do.call("rbind", data)
sf_dots <- sf_dots[sample(1:nrow(sf_dots)),]
return(sf_dots)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.