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

如何在R中循环变量过滤tibble并生成多组子集数据框?

按自定义时间段筛选数据框并生成子集

问题背景

现有如下结构的data.frame:

to.csv = structure(list(geography = c("030223131022122122", "030223131220201023", 
"030223131023121330", "030223131212130201", "030223131202323120", 
"030223131202033333", "030223131202003223", "030223131200111131", 
"030223131032003101", "030223131020030220"), xlon = c(-79.403, 
-79.44008, -79.30138, -79.20937, -79.39201, -79.40987, -79.44008, 
-79.36592, -79.2588, -79.43047), xlat = c(43.87067, 43.67234, 
43.87562, 43.75076, 43.71305, 43.73985, 43.75572, 43.83205, 43.88948, 
43.93895), bounds = c("-79.40369,43.87018,-79.40231,43.87117", 
"-79.44077,43.67184,-79.43939,43.67284", "-79.30206,43.87513,-79.30069,43.87612", 
"-79.21005,43.75027,-79.20868,43.75126", "-79.39270,43.71256,-79.39133,43.71355", 
"-79.41055,43.73935,-79.40918,43.74034", "-79.44077,43.75523,-79.43939,43.75622", 
"-79.36661,43.83155,-79.36523,43.83255", "-79.25949,43.88899,-79.25812,43.88998", 
"-79.43115,43.93845,-79.42978,43.93944"), start_date = c("2021-07-01", 
"2021-07-01", "2021-07-01", "2021-07-01", "2021-07-01", "2021-07-01", 
"2021-07-01", "2021-07-01", "2021-07-01", "2021-07-01"), end_date = c("2021-07-31", 
"2021-07-31", "2021-07-31", "2021-07-31", "2021-07-31", "2021-07-31", 
"2021-07-31", "2021-07-31", "2021-07-31", "2021-07-31"), agg_day_period = c(1L, 
1L, 1L, 0L, 1L, 1L, 0L, 1L, 1L, 0L), agg_time_period = c(20L, 
22L, 20L, 6L, 14L, 22L, 7L, 16L, 21L, 7L), activity_index_total = c(0.018224, 
0.020511, 0.070478, 0.054159, 0.037204, 0.036961, 0.046656, 0.415398, 
0.017664, 0.029587)), row.names = c(770468L, 955885L, 621962L, 
1164473L, 479957L, 588295L, 61790L, 1338380L, 1225032L, 688909L
), class = "data.frame")

需要按自定义时间段(例如wd_1_5 <- c(1:5)、wd_6_9 <- c(6:9))筛选数据框,生成多个子集用于后续转栅格,但尝试的代码未达预期:

wd_1_5 <- c(1:5)
wd_6_9 <- c(6:9)

time.periods <- c(wd_1_5, wd_6_9)

for(i in time.periods){
  df = to.csv %>%
    filter(agg_day_period == 1, agg_time_period %in% i) %>%
    group_by(geography, bounds)
  
  print(unique(df$agg_time_period))
}

问题分析

原代码的核心问题:

  • time.periods <- c(wd_1_5, wd_6_9)将两个时间段向量合并为单一向量,循环时i是单个数值而非完整时间段组,导致filter仅匹配单个agg_time_period值
  • 循环内每次覆盖df,未保留各时间段的子集
  • group_by后未执行聚合操作(如summarize),分组仅标记数据,未生成有用结果

解决方案

方法一:循环实现(保留子集到列表)

将时间段存入列表,循环遍历每个组,筛选后保存到结果列表:

# 定义时间段列表
time_period_list <- list(
  wd_1_5 = 1:5,
  wd_6_9 = 6:9
)

# 初始化空列表存储结果
result_list <- list()

# 循环处理每个时间段
for(period_name in names(time_period_list)){
  current_period <- time_period_list[[period_name]]
  # 筛选并按需聚合(示例计算activity均值)
  subset_df <- to.csv %>%
    filter(agg_day_period == 1, agg_time_period %in% current_period) %>%
    group_by(geography, bounds, xlon, xlat) %>%
    summarize(avg_activity = mean(activity_index_total, na.rm = TRUE), .groups = "drop")
  
  # 将子集存入结果列表,用时间段名称作为键
  result_list[[period_name]] <- subset_df
}

# 查看结果
result_list$wd_1_5
result_list$wd_6_9

方法二:高效的tidyverse分组方法

先给每个观测标记所属时间段组,再按组拆分或嵌套,更简洁:

library(dplyr)
library(tidyr)
library(purrr)

# 标记每个观测的时间段组
labeled_df <- to.csv %>%
  filter(agg_day_period == 1) %>%
  mutate(
    period_group = case_when(
      agg_time_period %in% 1:5 ~ "wd_1_5",
      agg_time_period %in% 6:9 ~ "wd_6_9",
      TRUE ~ "other" # 处理不在目标时间段的观测
    )
  )

# 方法1:按组拆分为数据框列表
split_list <- labeled_df %>%
  group_split(period_group, .keep = FALSE) %>%
  setNames(c("other", "wd_1_5", "wd_6_9")) # 根据实际分组顺序调整名称

# 方法2:嵌套数据框,方便后续批量处理(如转栅格)
nested_df <- labeled_df %>%
  group_by(period_group) %>%
  nest() %>%
  mutate(raster_data = map(data, function(df) {
    # 替换为实际转栅格代码,例如:
    # raster::rasterFromXYZ(df[, c("xlon", "xlat", "activity_index_total")])
    df # 示例保留数据框
  }))

说明

  • 两种方法均能生成对应时间段的子集,列表形式的结果方便后续批量处理(如循环转栅格)
  • 聚合步骤(summarize)可按需调整,若无需聚合可去掉group_by和summarize

内容的提问来源于stack exchange,提问作者Priya Patel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 22:32:06