使用非数值标识符时,如何获取R For Loop的迭代序号?
问题:获取循环迭代序号以调整PPT幻灯片位置
我编写了一个for循环,为crime_df中每个唯一的crime_type生成对应的地图,并将这些地图导出到PPT演示文稿pres_1中,代码如下:
for(i in unique(crime_df$crime_type)) { crime_map <- ggplot(data = filter(crime_df, crime_type== i)) + geom_sf(aes(geometry = geometry, fill = curr_yr_count)) pres_1 <- add_slide(pres_1, layout = "Title and Content", master = "Office Theme") pres_1 <- ph_with(pres_1, value = crime_map, location = ph_location_type(type = "body")) }我希望根据循环的迭代序号将生成的地图幻灯片移动到演示文稿的指定位置,例如第一个生成的地图移到第20张,第二个移到第22张等。但当前循环变量i对应的是非数值型的crime_type值(如robbery等)。请问是否有办法获取i对应的迭代数值,以便在循环末尾添加代码:
pres_1 <- move_slide(pres_1, index = length(pres_1), to = 22 + i)?
解决方案
方法1:遍历索引而非直接遍历crime_type值
先提取唯一的crime_type向量,然后遍历它的索引,既能拿到迭代序号,又能通过索引获取对应的crime_type值:
# 提前提取唯一的crime_type列表 unique_crimes <- unique(crime_df$crime_type) # 遍历索引(从1开始) for(idx in seq_along(unique_crimes)) { # 通过索引获取当前crime_type current_crime <- unique_crimes[idx] # 生成地图 crime_map <- ggplot(data = filter(crime_df, crime_type == current_crime)) + geom_sf(aes(geometry = geometry, fill = curr_yr_count)) # 添加幻灯片 pres_1 <- add_slide(pres_1, layout = "Title and Content", master = "Office Theme") pres_1 <- ph_with(pres_1, value = crime_map, location = ph_location_type(type = "body")) # 根据迭代序号计算目标位置:第一个到20,第二个到22,以此类推 target_pos <- 20 + (idx - 1)*2 pres_1 <- move_slide(pres_1, index = length(pres_1), to = target_pos) }
方法2:用purrr的imap函数(tidyverse风格)
如果你习惯使用tidyverse工具,purrr::imap可以同时获取元素和它的迭代索引:
library(purrr) unique_crimes <- unique(crime_df$crime_type) imap(unique_crimes, function(crime_type, idx) { # 生成地图 crime_map <- ggplot(data = filter(crime_df, crime_type == crime_type)) + geom_sf(aes(geometry = geometry, fill = curr_yr_count)) # 添加幻灯片(用<<-修改全局环境中的pres_1) pres_1 <<- add_slide(pres_1, layout = "Title and Content", master = "Office Theme") pres_1 <<- ph_with(pres_1, value = crime_map, location = ph_location_type(type = "body")) # 移动幻灯片 target_pos <- 20 + (idx - 1)*2 pres_1 <<- move_slide(pres_1, index = length(pres_1), to = target_pos) })
关键说明
- 迭代序号从1开始,所以目标位置计算公式
20 + (idx - 1)*2能精准匹配你的需求:第一个迭代对应20,第二个对应22,以此类推。 - 避免直接使用
22 + idx,否则第一个迭代会定位到23,不符合你的预期。
内容的提问来源于stack exchange,提问作者Ant
相关产品推荐
相关产品推荐

