I'm encountering an issue with my R code, and I'm not quite sure where I'm going wrong. The error message I'm receiving is 'Error in -title : invalid argument to unary operator> knitr::opts_chunk$set(echo = TRUE)
Error in discoveries[[matched$package]] <- TRUE : attempt to use zero-length variable name:', and the animation isn't displaying in the output HTML. However, it is saving as a GIF image on my local computer. The HTML output only shows the title and my name without the animation.
I'm relatively new to R, so any assistance would be greatly appreciated. If there's an alternative approach to achieving a temporal transition of maps displaying changes over time, please share it with me!
Here's the script I'm currently using:
title: "plot"
author: "Seyi Adebangbe"
date: "r Sys.Date()
"
output: html_document
knitr::opts_chunk$set(echo = TRUE)
knitr::include_graphics("C:\\Users\\seyib\\Downloads\\OneDrive_2022-09-08\\Getting confident with R\\Dependencies\\complete_animation.gif")
library(rgdal)
library(spNetwork)
library(sf)
library(tmap)
library(gifski)
library(classInt)
library(viridis)
setwd("C:/Users/seyib/Downloads/OneDrive_2022-09-08/Getting confident with R/Dependencies")
pipeline_v2 <- st_read("Smoothen_pipeline_Project1.shp")
spill_v3 <- st_read("Clipped_oil_spills_05_07_23.shp")
write.csv(spill_v3,"C:/Users/seyib/Downloads/OneDrive_2022-09-08/Getting confident with R/Dependencies/spill_v3_BAY.csv", row.names = TRUE)
write.csv(pipeline_v2,"C:/Users/seyib/Downloads/OneDrive_2022-09-08/Getting confident with R/Dependencies/pipeline_v2_BAY.csv", row.names = TRUE)
lixels <- lixelize_lines(pipeline_v2, 500, 50)
sample_points <- lines_center(lixels)
distances <- st_distance(spill_v3, pipeline_v2)
Best_dist <- apply(distances, 1, min)
ok_pts <- subset(spill_v3, Best_dist < 500)
# To remove rows with NAs
ok_pts <- na.omit(ok_pts)
print(ok_pts$Incident_D)
# creating a numeric vector for temporal column
ok_pts$Time <- as.POSIXct(ok_pts$Incident_D, format = "%d/%m/%Y", origin = "29-05-2008")
start <- as.POSIXct("2008/05/29", format = "%Y/%m/%d")
# Convert Incident_D to POSIXct format
ok_pts$Time <- as.POSIXct(ok_pts$Incident_D, origin = "2008-05-29", tz = "UTC")
# Create the numeric vector for temporal column
start <- min(ok_pts$Time)
ok_pts$Time_num <- as.numeric(difftime(ok_pts$Time, start, units = "days"))
# Verify the newly created column
print(ok_pts$Time_num)
#ok_pts$Time_num <- difftime(ok_pts$Time, start, units = "days")
#ok_pts$Time_num <- as.numeric(ok_pts$Time_num)
#print(ok_pts)
# Create the numeric vector for temporal column
ok_pts$Time_num <- as.numeric(difftime(ok_pts$Time, start, units = "days"))
# Verify the newly created column
#print(ok_pts$Time_num)
# Filter out missing or non-finite values
valid_values <- ok_pts$Time_num[is.finite(ok_pts$Time_num) & !is.na(ok_pts$Time_num)]
# Check the valid_values vector
#print(valid_values)
# Calculate the maximum value
max_value <- max(valid_values)
# Check the maximum value
#print(max_value)
# Generate the sample time vector
if (length(valid_values) > 0) {
sample_time <- seq(0, max_value, 100)
} else {
# Provide a default value or handle it as per your requirement
sample_time <- c(0) # Set sample_time to a default value, such as 0
}
#print(sample_time) # Print the sample_time to check its value
# Generate the sample time vector
#sample_time <- seq(0, max_value, 10)
sample_time <- seq(0, max(ok_pts$Time_num), 100)
tnkde_densities <- tnkde(lines = pipeline_v2,
events = ok_pts,
time_field = "Time_num",
samples_loc = sample_points,
samples_time = sample_time,
w = rep(1,nrow(ok_pts)),
kernel_name = "quartic",
bw_net = 700, bw_time = 90,
adaptive = TRUE,
trim_bw_net = 900,
trim_bw_time = 120,
method = "continuous",
div = "bw",
max_depth = 10,
digits = 2, tol = 0.1, agg = 15,
grid_shape = c(1,1),
verbose = TRUE)
# Extract the kernel density estimates
densities <- tnkde_densities$k
# Reshape the densities vector into a matrix
num_pts <- nrow(sample_points)
num_times <- length(sample_time)
densities_matrix <- matrix(densities, nrow = num_pts, ncol = num_times, byrow = FALSE)
# Create a color palette for all the densities
library(classInt)
library(viridis)
all_densities <- c(densities_matrix)
color_breaks <- classIntervals(all_densities, n = 10, style = "kmeans")
# Generate the maps at each sample time
all_maps <- lapply(seq_len(num_times), function(i) {
time <- sample_time[i]
date <- as.Date(start) + time
sample_points$density <- densities_matrix[, i]
map <- tm_shape(sample_points) +
tm_dots(col = "density", size = 0.02,
breaks = color_breaks$brks, palette = plasma(10)) +
tm_layout(legend.show = FALSE, main.title = as.character(date), main.title.size = 0.4)
return(map)
})
# Create a directory to save individual frames
frame_directory <- "frames"
dir.create(frame_directory, showWarnings = FALSE)
# Save each frame as a separate PNG file
for (i in seq_along(all_maps)) {
time <- sample_time[i]
date <- as.Date(start) + time
sample_points$density <- densities_matrix[, i]
map <- tm_shape(sample_points) +
tm_dots(col = "density", size = 0.5,
breaks = color_breaks$brks, palette = plasma(10)) +
tm_layout(legend.show = FALSE, main.title = as.character(date), main.title.size = 2.)
# Save the map as an individual PNG file
frame_filename <- sprintf("%s/frame_%03d.png", frame_directory, i)
tmap_save(map, filename = frame_filename, width = 10000, height = 10000, dpi = 1000)
}
# Display the animation
library(gifski)
animation <- tmap_animation(all_maps, width = 500, height = 500, dpi = 100, delay = 200, frames = num_times)
# Save the complete GIF file
animation_file <- "complete_animation.gif"
gifski::save_gif(animation, animation_file)
# Print the animation
animation
animation_file