stats_sf can't find geometry aesthetics

Hi, I'm trying to gganimate a map, I'm able to do a simple map using renewable energy data from the world bank but when in order to animate it I need to add the years variable in the dataframe, first I join the dataframes (geometry and data)with the years as the name for each column with the data and then I make a pivot longer to create one Value for each year and country. But after doing this when I try to plot the map with geom_sf, I get the following error: "stat_sf requires the following missing aesthetics: geometry" . Any idea? what am I doing wrong?

Here is my code :

 library(tidyverse)
library(rio)
library(plotly)
library(janitor)
library(gganimate)
library(viridis)
library("sf")
library(tidyverse)
library(rio)
url <-("https://raw.githubusercontent.com/rodri45l/plasticwaste/main/trabajo_BigData_equipo/datos/renpwr.csv")

df <- import(url)

df_pwr<- df %>% select(-c(`Series Name`,`Series Code`))  %>% rename(sovereignt = `Country Name`,
                                                                                                `1990` = `1990 [YR1990]`,
                                                                                                `1991`=`1991 [YR1991]`,
                                                                                                `1992`=`1992 [YR1992]`,
                                                                                                `1993`=`1993 [YR1993]`,
                                                                                                `1994`=`1994 [YR1994]`,
                                                                                                `1995`=`1995 [YR1995]`,
                                                                                                `1996`=`1996 [YR1996]`,
                                                                                                `1997`=`1997 [YR1997]`,
                                                                                                `1998`=`1998 [YR1998]`,
                                                                                                `1999`=`1999 [YR1999]`,
                                                                                                `2000`=`2000 [YR2000]`,
                                                                                                `2001`=`2001 [YR2001]`,
                                                                                                `2002`=`2002 [YR2002]`,
                                                                                                `2003`=`2003 [YR2003]`,
                                                                                                `2004`=`2004 [YR2004]`,
                                                                                                `2005`=`2005 [YR2005]`,
                                                                                                `2006`=`2006 [YR2006]`,
                                                                                                `2007`=`2007 [YR2007]`,
                                                                                                `2008`=`2008 [YR2008]`,
                                                                                                `2009`=`2009 [YR2009]`,         
                                                                                                `2010`=`2010 [YR2010]`,
                                                                                                `2011`=`2011 [YR2011]`,
                                                                                                `2012`=`2012 [YR2012]`,
                                                                                                `2013`=`2013 [YR2013]`,
                                                                                                `2014`=`2014 [YR2014]` ,  
                                                                                                `2015`=`2015 [YR2015]`
                                                                                                
) 




df_pwr2 <- df_pwr %>%  pivot_longer(cols = 3:28, names_to = "year") %>% transform(year = as.numeric(year),
                                                                                  value = as.numeric(value)
) %>% filter(year == 2015)






world <- rnaturalearth::ne_countries(scale = "medium", returnclass = "sf")
world_points<- st_centroid(world)
world_points <- cbind(world, st_coordinates(st_centroid(world$geometry)))










df_pwr2$sovereignt <- recode(df_pwr2$sovereignt, 
                             "United States"="United States of America", 
                             "Russian Federation" = "Russia",
                             "Venezuela, RB" = "Venezuela",
                             "Congo, Dem. Rep." = "Democratic Republic of the Congo" ,
                             "	Congo, Rep."="Republic of Congo"	 ,
                             "Egypt, Arab Rep." = "Egypt" ,
                             "Tanzania" = "United Republic of Tanzania",
                             "Cote d'Ivoire" = "Ivory Coast",
                             "Yemen, Rep." = "Yemen",
                             "Iran, Islamic Rep." = "Iran",
                             "Syrian Arab Republic" = "Syria",
                             "Slovak Republic" = "Slovakia",
                             "Serbia" = "Republic of Serbia",
                             "North Macedonia" = "Macedonia",
                             "Kyrgyz Republic" = "Kyrgyzstan",
                             "Korea, Dem. People’s Rep" = "North Korea",
                             "Korea, Rep." = "South Korea",
                             "Lao PDR" = "Laos")


df_inner_pwr <- merge(world,df_pwr2,by="sovereignt",all=TRUE)


#First map
p <- ggplot(data = df_inner_pwr) + geom_sf() +
  labs(title = "Gráfico 1: Mapa del mundo energias renovables",
       caption = "Datos provenientes de World Bank")


p+ geom_sf(aes(fill = value, color =value)) + scale_fill_viridis(direction = 1, label = scales::dollar,begin = 0, end = 0.9) + 
  scale_color_viridis(direction = 1, label = scales::dollar,begin = 0, end = 0.9) 


#Trying to gganimate the map



df_pwr$sovereignt <- recode(df_pwr$sovereignt, 
                            "United States"="United States of America", 
                            "Russian Federation" = "Russia",
                            "Venezuela, RB" = "Venezuela",
                            "Congo, Dem. Rep." = "Democratic Republic of the Congo" ,
                            "	Congo, Rep."="Republic of Congo"	 ,
                            "Egypt, Arab Rep." = "Egypt" ,
                            "Tanzania" = "United Republic of Tanzania",
                            "Cote d'Ivoire" = "Ivory Coast",
                            "Yemen, Rep." = "Yemen",
                            "Iran, Islamic Rep." = "Iran",
                            "Syrian Arab Republic" = "Syria",
                            "Slovak Republic" = "Slovakia",
                            "Serbia" = "Republic of Serbia",
                            "North Macedonia" = "Macedonia",
                            "Kyrgyz Republic" = "Kyrgyzstan",
                            "Korea, Dem. People’s Rep" = "North Korea",
                            "Korea, Rep." = "South Korea",
                            "Lao PDR" = "Laos")
df_pwr4 <- merge(world,df_pwr,by="sovereignt",all=TRUE)
df_pwr6 <- df_pwr4 %>%  pivot_longer(cols = 65:90, names_to = "year") %>% transform(year = as.numeric(year),
                                                                                    value = as.numeric(value)) 





o <- ggplot(data = df_pwr6) + geom_sf(data = df_pwr6, aes(fill = value)) +
  labs(title = "Gráfico 1: Mapa del mundo energias renovables",
       caption = "Datos provenientes de World Bank")


o + geom_sf(aes(fill = value, color =value)) + scale_fill_viridis(direction = 1, label = scales::number,begin = 0, end = 0.9) + 
  scale_color_viridis(direction = 1, label = scales::number,begin = 0, end = 0.9) + transition_reveal(year) +
  labs(title = "year: {as.integer(frame_along)}")

Your code is complex and not quite easy to troubleshoot; it might be a good idea to reframe the issue you are facing in as simple format as possible. What you share is quite a chunk...

For a simple example of spatial data frame animated via {gganimate} consider this post; it builds on the pressure dataset that is shipped with base R and the North Carolina shapefile that comes with {sf}.

@jlacko Thanks for answering; my bad, didn't think my code was so big or complex. I guess I'll have to re think the way to do it. Your example helped me a lot. Thanks again.

It is not a huge piece of code, but a sizable one; most of seems not directly relevant to your issue (animating a geom_sf). You also import a number of libraries, listing some of them twice. This can be tricky - for example I don't have {rio} installed and so I am unable to run your code as it stands now.

In general it is a good idea when you run into a problem with a piece of code to simplify it into a minimal reproducible example - focusing only on the tricky part, and cutting out the chaff.

I know it is harder than it sounds, but by making it easier for others to help you you are increasing your chances for a quality answer.

On second thought - I have managed to install {rio} - it seems that the immediate cause of failure of your geom_sf() call is due to class of your df_pwr6 object being "only" data.frame.

It has lost its special sf sauce. Likely this is a result of your pivot_longer() call, when you select only columns 65 to 90, omitting the special geometry column.

1 Like

I managed to fix it, the problem was gganimate doesn't recognize geometry when it's not in the last column, so just add geometry = geometry in aes().

geom_sf(data = .... , aes(geometry = geometry, .... ))

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.