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

如何在R语言中实现近似筛选最大方差基因型子集的迭代算法?

用R实现近似寻找最大方差子集的方案

没问题,我帮你搞定这个需求——因为穷举所有子集完全不现实,咱们就用你提出的贪心迭代近似方法,从20个基因型里选出10个方差最大的子集,下面是具体实现:

第一步:准备示例数据

首先先把你给的示例数据定义好:

# 示例基因型数据
Genotype <-c("BK001","BK002","BK003","BK004","BK005","BK006","BK007","BK008","BK009","BK010", 
             "BK011","BK012","BK013","BK014","BK015","BK016","BK017","BK018","BK019","BK020")
Protein <- c(13.25287,14.34778,13.87116,14.00869,14.77897,14.43378,15.89361,15.96695,13.78778, 
             12.84457,12.99955,14.28378,14.15799,12.42578,14.80507,13.56095,15.26557,14.45378,13.06739, 
             14.34230)
my_df <- data.frame(Genotype, Protein)

第二步:实现核心逻辑

咱们按照你提出的流程来,不过我优化了初始步骤——直接从所有3元素组合里找方差最大的,比“min+max+随机”的初始候选更接近最优,当然如果你坚持原初始方式,后面我会给出修改方案。

2.1 定义辅助函数

先写个小函数用来计算子集的方差:

# 计算给定索引对应的Protein子集的方差
get_subset_var <- function(subset_indices, df) {
  var(df$Protein[subset_indices])
}

2.2 找到最优初始3元素子集

遍历所有可能的3元素组合,选出方差最大的那个作为迭代起点:

# 生成所有3元素的索引组合
all_3comb <- combn(nrow(my_df), 3)
# 计算每个组合的方差
var_3comb <- apply(all_3comb, 2, get_subset_var, df = my_df)
# 找到方差最大的3元素组合
max_var_3_idx <- all_3comb[, which.max(var_3comb)]
current_subset <- my_df[max_var_3_idx, ]
remaining_df <- my_df[-max_var_3_idx, ]

2.3 迭代扩展子集到目标大小

每次从剩余元素里选一个加入当前子集,让新子集的方差最大,直到子集大小达到10:

# 目标子集大小
target_size <- 10

# 开始迭代
while(nrow(current_subset) < target_size) {
  candidate_vars <- c()
  
  # 逐个测试剩余元素加入后的方差
  for(i in 1:nrow(remaining_df)) {
    temp_subset <- rbind(current_subset, remaining_df[i, ])
    candidate_vars <- c(candidate_vars, var(temp_subset$Protein))
  }
  
  # 选出让方差最大的元素
  best_idx <- which.max(candidate_vars)
  # 更新当前子集和剩余数据
  current_subset <- rbind(current_subset, remaining_df[best_idx, ])
  remaining_df <- remaining_df[-best_idx, ]
  
  # 可选:打印进度,方便追踪
  cat(sprintf("当前子集大小:%d,当前方差:%.4f\n", nrow(current_subset), var(current_subset$Protein)))
}

第三步:查看结果

运行完循环后,直接输出最终的子集和它的方差:

cat("方差最大的10个基因型子集:\n")
print(current_subset)
cat(sprintf("\n该子集的Protein方差为:%.4f", var(current_subset$Protein)))

可选:使用你原描述的初始子集

如果你想严格按照“min+max+任意剩余元素”作为初始,替换掉2.2的代码即可:

# 找到Protein最小和最大的基因型索引
min_idx <- which.min(my_df$Protein)
max_idx <- which.max(my_df$Protein)
# 从剩余元素里随机选一个
remaining_idx <- setdiff(1:nrow(my_df), c(min_idx, max_idx))
random_idx <- sample(remaining_idx, 1)
# 初始化子集
current_subset <- my_df[c(min_idx, max_idx, random_idx), ]
remaining_df <- my_df[-c(min_idx, max_idx, random_idx), ]

注意事项

  • 这个方法是贪心近似算法:它每一步都选当前最优的选项,不能保证找到全局绝对最优的子集,但在计算效率和结果质量之间做了很好的平衡,非常适合你提到的150选75这种大规模场景。
  • 如果你需要多次运行取更稳定的结果,可以把初始随机选择(如果用原初始方式)或者整个流程重复几次,取方差最大的那个最终子集。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 20:07:32