如何将DataFrame按组拆分并随机分配UN组行至10个子DataFrame?
实现方法
我们可以分四步完成这个需求,核心是先保证非UN分组的完整性,再均衡分配UN行:
1. 分离数据
先把原数据拆成非UN分组集合和UN行集合两部分:
# 示例数据 df <- data.frame( ID = c("1234", "edje", "hgt1", "4567", "0900", "wwwl", "yyyt", "5789", "hlkk", "3333"), group = c("V1", "V1", "V2", "V2", "V2", "V3", "V3", "UN", "UN", "UN") ) # 分离非UN分组和UN行 non_un_groups <- df[df$group != "UN", ] un_rows <- df[df$group == "UN", ]
2. 给非UN分组分配目标子DataFrame
我们需要将每个完整的非UN分组分配到10个子DF中,保证每个子DF的行数尽量均衡:
library(dplyr) # 计算每个非UN分组的行数 group_sizes <- non_un_groups %>% group_by(group) %>% summarise(size = n(), .groups = "drop") %>% arrange(desc(size)) # 按分组大小降序排列 # 初始化10个桶,记录每个桶的当前总行数和包含的分组 bucket_sizes <- rep(0, 10) bucket_groups <- vector("list", 10) # 贪心分配:每次把最大的剩余分组放到当前最小的桶里 for (i in 1:nrow(group_sizes)) { target_bucket <- which.min(bucket_sizes) bucket_groups[[target_bucket]] <- c(bucket_groups[[target_bucket]], group_sizes$group[i]) bucket_sizes[target_bucket] <- bucket_sizes[target_bucket] + group_sizes$size[i] }
3. 随机分配UN行到10个子DataFrame
把UN行随机分成10份,每份数量尽量平均:
set.seed(123) # 设置随机种子保证结果可复现 un_assignments <- sample(1:10, nrow(un_rows), replace = TRUE) # 调整分配,让每个桶的UN行数更均衡 un_counts <- table(un_assignments) while(any(un_counts - min(un_counts) > 1)) { over_bucket <- which.max(un_counts) under_bucket <- which.min(un_counts) move_idx <- which(un_assignments == over_bucket)[1] un_assignments[move_idx] <- under_bucket un_counts <- table(un_assignments) } # 按分配结果拆分UN行 un_split <- split(un_rows, un_assignments)
4. 合并并生成最终的子DataFrames
将每个桶的非UN分组数据和对应的UN行合并,得到10个子DF:
final_dfs <- vector("list", 10) for (i in 1:10) { # 获取当前桶的非UN分组数据 non_un_data <- non_un_groups[non_un_groups$group %in% bucket_groups[[i]], ] # 合并UN行 final_dfs[[i]] <- rbind(non_un_data, un_split[[as.character(i)]]) # 可选:重置行名 rownames(final_dfs[[i]]) <- NULL }
验证示例结果
运行上述代码后,final_dfs就是包含10个子DataFrame的列表。以示例数据为例,其中几个子DF的结果如下(因随机分配可能略有不同):
# 查看第一个子DF final_dfs[[1]] # ID group # 1 1234 V1 # 2 edje V1 # 3 5789 UN # 查看第二个子DF final_dfs[[2]] # ID group # 1 hgt1 V2 # 2 4567 V2 # 3 0900 V2 # 4 hlkk UN
内容的提问来源于stack exchange,提问作者Khaleesi95
相关产品推荐
相关产品推荐

