You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

geom_sf/gganimate/shadow_mark代码报‘Replacement has x rows’错误求助

问题描述

我有多物种在不同地点的多年份观测数据,部分年份无数据,想要制作包含无数据年份的动画地图,此前成功实现但现在失效。以下是可复现代码及错误信息:

可复现代码

数据准备

library(sf)
library(ggplot2)
library(gganimate)
library(transformr)
library(tidyr)

rb <- data.frame(YEAR = c(1995, 2000, 2000, 2001, 2002, 2002, 2002, 2004), 
                 TOTAL = c(5, 10, 8, 14, 15, 12, 16, 15),
                 LONG = c(runif(8, -80, -78)),
                 LAT = c(runif(8, 38, 40)))

填充缺失年份数据

rb.zero.df <- data.frame(rb %>% 
                           complete(YEAR = full_seq(1995:2004, 1), 
                                    fill = list(LONG = -78.3893, 
                                                LAT = 39.63938, 
                                                TOTAL = 0)))

rb.zero <- st_as_sf(rb.zero.df, coords = c("LONG", "LAT"), crs = 4326)

动画地图代码

rb.zero.map <- ggplot() +
  geom_sf(data = rb.zero, aes(size = TOTAL, alpha = ifelse(TOTAL == 0, 0, 1))) +
  scale_alpha(range = c(0,1)) +
  guides(alpha = "none") +
  transition_states(YEAR, transition_length = 0, state_length = 1) +
  ggtitle("{closest_state}") +
  shadow_mark(alpha = ifelse(rb.zero$TOTAL == 0, 0, 0.25))
animate(rb.zero.map)

错误信息

Error in `[[<-.data.frame`(`*tmp*`, i, value = c(0.25, 0, 0, 0, 0, 0.25,  : 
  replacement has 13 rows, data has 12

移除shadow_mark中的ifelse后代码可正常运行,数据和代码未变更,不知为何失效,恳请排查原因或提供替代方案。

会话信息

R version 4.3.2 (2023-10-31)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Ventura 13.3.1

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.11.0

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: America/New_York
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] transformr_0.1.3      gifski_1.12.0-2       gganimate_1.0.7       tidyr_1.3.0          
 [5] viridis_0.6.4         viridisLite_0.4.2     spData_2.3.0          dplyr_1.1.4          
 [9] terra_1.7-65          sf_1.0-15             ggplot2_3.4.4         leaflet.extras2_1.2.2
[13] leaflet_2.2.1         tmap_3.99.9000        

loaded via a namespace (and not attached):
 [1] DBI_1.2.1               gridExtra_2.3           tmaptools_3.1-1         remotes_2.4.2.1        
 [5] rlang_1.1.3             magrittr_2.0.3          e1071_1.7-14            compiler_4.3.2         
 [9] mgcv_1.9-0              png_0.1-8               vctrs_0.6.5             stringr_1.5.1          
[13] profvis_0.3.8           pkgconfig_2.0.3         crayon_1.5.2            fastmap_1.1.1          
[17] ellipsis_0.3.2          labeling_0.4.3          lwgeom_0.2-13           leafem_0.2.3           
[21] utf8_1.2.4              promises_1.2.1          sessioninfo_1.2.2       purrr_1.0.2            
[25] cachem_1.0.8            progress_1.2.3          later_1.3.2             tweenr_2.0.2           
[29] parallel_4.3.2          prettyunits_1.2.0       R6_2.5.1                stringi_1.8.3          
[33] RColorBrewer_1.1-3      pkgload_1.3.4           stars_0.6-4             Rcpp_1.0.12            
[37] usethis_2.2.2           base64enc_0.1-3         leaflet.providers_2.0.0 Matrix_1.6-1.1         
[41] httpuv_1.6.13           splines_4.3.2           tidyselect_1.2.0        rstudioapi_0.15.0      
[45] dichromat_2.0-0.1       abind_1.4-5             codetools_0.2-19        miniUI_0.1.1.1         
[49] pkgbuild_1.4.3          lattice_0.21-9          tibble_3.2.1            leafsync_0.1.0         
[53] plyr_1.8.9              shiny_1.8.0             withr_3.0.0             units_0.8-5            
[57] proxy_0.4-27            urlchecker_1.0.1        lpSolve_5.6.20          pillar_1.9.0           
[61] KernSmooth_2.23-22      generics_0.1.3          sp_2.1-2                hms_1.1.3              
[65] munsell_0.5.0           scales_1.3.0            xtable_1.8-4            class_7.3-22           
[69] glue_1.7.0              tools_4.3.2             leaflegend_1.2.0        data.table_1.14.10     
[73] fs_1.6.3                XML_3.99-0.16.1         grid_4.3.2              crosstalk_1.2.1        
[77] devtools_2.4.5          colorspace_2.1-0        nlme_3.1-163            cols4all_0.7           
[81] raster_3.6-26           cli_3.6.2               fansi_1.0.6             gtable_0.3.4           
[85] digest_0.6.34           widgetframe_0.3.1       classInt_0.4-10         htmlwidgets_1.6.4      
[89] farver_2.1.1            memoise_2.0.1           htmltools_0.5.7         lifecycle_1.0.4        
[93] mime_0.12 

原因分析与解决方案

错误原因

shadow_mark在配合transition_states生成动画时,会自动扩展数据集以包含历史状态的元素。直接引用原始数据的ifelse(rb.zero$TOTAL == 0, 0, 0.25)会导致长度不匹配——原始数据有12行,但动画帧处理后的数据行数变为13,触发维度错误。

替代方案

不要直接在shadow_mark中传入原始数据的向量,而是通过映射美学变量的方式控制透明度,让gganimate自动适配数据长度:

方案1:提前在数据中添加阴影透明度列

# 给rb.zero新增shadow_alpha列
rb.zero$shadow_alpha <- ifelse(rb.zero$TOTAL == 0, 0, 0.25)

# 动画代码中映射该列到shadow_mark的alpha参数
rb.zero.map <- ggplot() +
  geom_sf(data = rb.zero, aes(size = TOTAL, alpha = ifelse(TOTAL == 0, 0, 1))) +
  scale_alpha(range = c(0,1)) +
  guides(alpha = "none") +
  transition_states(YEAR, transition_length = 0, state_length = 1) +
  ggtitle("{closest_state}") +
  shadow_mark(aes(alpha = shadow_alpha))

animate(rb.zero.map)

方案2:在shadow_mark中直接使用条件映射

直接在shadow_mark的aes内编写条件逻辑,让gganimate基于当前帧的数据计算透明度:

rb.zero.map <- ggplot() +
  geom_sf(data = rb.zero, aes(size = TOTAL, alpha = ifelse(TOTAL == 0, 0, 1))) +
  scale_alpha(range = c(0,1)) +
  guides(alpha = "none") +
  transition_states(YEAR, transition_length = 0, state_length = 1) +
  ggtitle("{closest_state}") +
  shadow_mark(aes(alpha = ifelse(TOTAL == 0, 0, 0.25)))

animate(rb.zero.map)

说明

两种方案都能让gganimate自动适配动画帧的数据长度,避免维度不匹配问题。方案1适合提前处理复杂逻辑,方案2更简洁,适合简单条件判断。

内容的提问来源于stack exchange,提问作者Molly Cohn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 08:49:55