如何按每90条观测值拆分数据集?求最优实现方案
拆分数据集并生成14列DataFrame的最优方案
问题概述
我有3个各含1368行的数据集,需要按顺序将每个数据集拆分为每组90条的子集(最后一组可包含更多数据),最终生成14列的DataFrame,用于后续t检验等统计分析。以下是示例代码和预期输出:
示例代码
# 生成示例数据 a <- sample(0:10000, 1368, rep=TRUE) Df <- data.frame(obs=c(1:1368), var1=a) # 手动拆分前3组的示例 df2 <- data.frame(col1=Df$var1[1:90], col2=Df$var1[91:180], col3=Df$var1[181:270])
预期输出片段
Dataset 1(前7行)
| col1 | col2 | col3 |
|---|---|---|
| 7878 | 8130 | 3924 |
| 5781 | 4375 | 6232 |
| 9324 | 9066 | 1734 |
| 9754 | 8796 | 2047 |
| 3462 | 4930 | 7381 |
| 7379 | 8103 | 3404 |
| 7355 | 5212 | 4505 |
Dataset 2(前14行)
| col1 | col2 | col3 |
|---|---|---|
| 7878 | 8130 | 3924 |
| 5781 | 4375 | 6232 |
| 9324 | 9066 | 1734 |
| 9754 | 8796 | 2047 |
| 3462 | 4930 | 7381 |
| 7379 | 8103 | 3404 |
| 7355 | 5212 | 4505 |
| 5599 | 6887 | 5775 |
| 2321 | 7948 | 3553 |
| 3717 | 1248 | 5818 |
| 6276 | 5528 | 206 |
| 1328 | 1158 | 8681 |
| 4470 | 3009 | 1332 |
| 6472 | 9018 | 606 |
最优解决方案
核心逻辑
按要求拆分后,前13组每组90条数据,第14组包含剩余的1368 - 13*90 = 198条数据。为了生成结构统一的DataFrame,短组的缺失行用NA填充,保证所有列长度一致。
方法1:Base R实现(无需额外包)
# 定义通用拆分函数 split_to_14cols <- function(data, group_size = 90) { # 提取目标变量列 val_vec <- data$var1 total_len <- length(val_vec) # 计算14组的索引范围 group_indices <- lapply(1:14, function(i) { start <- (i-1)*group_size + 1 # 最后一组取到末尾,前面的组取group_size条 end <- ifelse(i == 14, total_len, min(i*group_size, total_len)) start:end }) # 提取每组数据并补全NA到最长组的长度 col_data <- lapply(group_indices, function(idx) { vec <- val_vec[idx] length(vec) <- max(sapply(group_indices, length)) vec }) # 合并为DataFrame并命名列 result <- do.call(data.frame, col_data) colnames(result) <- paste0("col", 1:14) return(result) } # 测试函数 a <- sample(0:10000, 1368, rep=TRUE) Df <- data.frame(obs=c(1:1368), var1=a) final_df <- split_to_14cols(Df) # 查看结果结构 str(final_df)
方法2:Tidyverse工具链实现(dplyr + tidyr)
如果习惯用tidyverse生态,代码更简洁易读:
library(dplyr) library(tidyr) split_to_14cols_tidy <- function(data, group_size = 90) { data %>% # 分配组ID:前13组按90条划分,第14组包含剩余所有 mutate(group = if_else(row_number() <= 13*group_size, ceiling(row_number()/group_size), 14)) %>% # 为每组生成组内行号,用于宽表转换 group_by(group) %>% mutate(row_id = row_number()) %>% ungroup() %>% # 转换为宽表,列对应组,行对应组内位置 pivot_wider(id_cols = row_id, names_from = group, values_from = var1, names_prefix = "col") } # 测试 final_df_tidy <- split_to_14cols_tidy(Df)
多数据集处理
如果要处理3个数据集,只需循环调用上述函数,再用bind_cols合并即可:
# 假设你有三个数据集df1, df2, df3 processed_dfs <- lapply(list(df1, df2, df3), split_to_14cols) combined_df <- do.call(bind_cols, processed_dfs)
内容的提问来源于stack exchange,提问作者JD kreyfelt
相关产品推荐
相关产品推荐

