Dear Team,
Many thanks for this opportunity for R beginners like me to share their problems and seek for help from the community.
My issue is, I was supposed to create some animation map in R. I have very basic knowhow about R, but I love coding with it though. However, whenever I try to run my code it just gives me the below message,
Error in $<-.data.frame
(*tmp*
, "id", value = c(1L, 1L, 1L, 1L, 1L, :
replacement has 2886 rows, data has 2826
I don't know how to fix it, so please I need anyone herein to support. Thanks a lot!
Below is my R code:
libraries
libs <- c(
"tidyverse", "sf", "rnaturalearth","ggmap",
"wbstats", "gganimate", "classInt", "ggplot2"
)
install missing libraries
installed_libs <- libs %in% rownames(installed.packages())
if (any(installed_libs == FALSE)) {
install.packages(libs[!installed_libs])
}
load libraries
invisible(lapply(libs, library, character.only = TRUE))
1. IMPORT DATA
#-----------
install.packages("readxl")
library("readxl")
setwd("D:\R Tutorial\Animate in R\animate-maps-with-r-main\animate-maps-with-r-main\R\Test")
number_benef_df <- read_excel("Number_of_Benificiary2.xlsx")
View(number_benef_df)
number_benef_df_vector <- as.vector(number_benef_df)
fix(number_benef_df_vector)
2. ETH SHAPEFILE
#-------------------
ETH_Woreda <- st_read("draft_ETH_Admins_2024\ETH_Woredas.shp")
View(ETH_Woreda)
names(ETH_Woreda)
plot(sf::st_geometry(ETH_Woreda))
3. JOIN DATA & SHAPEFILE
#-------------------------
number_benef_sf <- dplyr::inner_join(
ETH_Woreda, number_benef_df,
by = c("admin3Pcod" = "Woreda_Pcode")
)
View(number_benef_sf)
4. BREAKS
#----------
vmin <- min(number_benef_sf$NO_Beneficiary, na.rm = T)
vmax <- max(number_benef_sf$NO_Beneficiary, na.rm = T)
brk <- round(classIntervals(
number_benef_sf$NO_Beneficiary,
n = 6,
style = "fisher"
)
$brks, 1) |>
head(-1) |>
tail(-1) |>
append(vmax)
breaks <- c(vmin, brk)
cols <- rev(c(
"#001f3a", "#30314e", "#5c435f",
"#8d5369", "#c0636c", "#dc8177",
"#e6a988"
))
5. ANIMATE
#-----------
get_animated_number_benef_map <- function() {
benef_map <- ggplot(
data = number_benef_sf,
aes(fill = NO_Beneficiary)
) +
geom_sf(data = ETH_Woreda, fill = NA, size = 0.05, color = "grey70")+
geom_sf(color = "grey70", size = 0.05) +
scale_fill_gradientn(
name = "",
colours = cols,
breaks = breaks,
labels = round(breaks, 1),
limits = c(vmin, vmax),
na.value = "grey70"
) +
coord_sf() +
guides(fill = guide_legend(
direction = "horizontal",
keyheight = unit(1.5, units = "mm"),
keywidth = unit(15, units = "mm"),
title.position = "top",
title.hjust = .5,
label.hjust = .5,
nrow = 1,
byrow = T,
reverse = F,
label.position = "bottom"
)) +
theme_minimal() +
theme(
axis.line = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank(),
axis.ticks = element_blank(),
axis.title.x = element_blank(),
axis.title.y = element_blank(),
legend.position = c(.5, -.015),
legend.text = element_text(size = 11, color = "grey10"),
panel.grid.major = element_line(color = "white", size = .2),
panel.grid.minor = element_blank(),
plot.title = element_text(
face = "bold", size = 20,
color = "grey10", hjust = .5, vjust = -3
),
plot.subtitle = element_text(
size = 40, color = "#c43c4e",
hjust = .5, vjust = -1
),
plot.caption = element_text(
size = 10, color = "grey10",
hjust = .5, vjust = -10
),
plot.margin = unit(c(t = -.1, r = -2, b = -.1, l = -2), "lines"),
plot.background = element_rect(fill = "white", color = NA),
panel.background = element_rect(fill = "white", color = NA),
legend.background = element_rect(fill = "white", color = NA),
panel.border = element_blank()
) +
labs(
x = "",
y = "",
title = "Benefiary Map"
)
return(benef_map)
}
benef_map <- get_animated_number_benef_map()
print(benef_map)
timelapse_benef_map <- benef_map +
gganimate::transition_time(
time = as.Date(Start_Year)
) +
enter_fade() +
exit_fade() +
ease_aes("quadratic-in-out", interval = .2)
animated_benef_map <- gganimate::animate(
timelapse_benef_map,
nframes = 120,
duration = 20,
start_pause = 3,
end_pause = 30,
height = 6,
width = 7.15,
res = 300,
units = "in",
fps = 15,
renderer = gifski_renderer(loop = T)
)
gganimate::anim_save(
"beneficiary_map.gif", animated_benef_map
)