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

R语言中循环索引j被忽略,多组数据未处理问题排查

问题原因分析

你的代码核心问题是双层循环的结果存储逻辑错误,导致除最后一次迭代的分组外,其他分组的数据全部被覆盖丢失:

  1. 外层循环遍历分组j,内层循环遍历方法i时,每次都将results[[i]]赋值为当前j分组的i方法结果。这意味着当你处理下一个分组时,会直接覆盖之前所有方法对应的结果,最终results列表里只保留了最后一个分组的所有方法数据。
  2. 最后用do.call(cbind.data.frame, results)做列合并,会把同一个分组的多方法结果强行拼在一起,完全丢失其他分组的信息,最终只能看到最后一个分组的数据(你看到的A分组,说明在你的环境中最后一次j循环处理的是A)。
修复后的代码

以下代码调整了结果存储逻辑,先按分组生成完整的方法结果数据框,再通过行合并保留所有分组的数据:

library(stringdist)
library(tidyverse)

set.seed(123)
# 生成数据集
myFun <- function(n = 5000) {
  a <- do.call(paste0, replicate(5, sample(LETTERS, n, TRUE), FALSE))
  paste0(a, sprintf("%04d", sample(9999, n, TRUE)), sample(LETTERS, n, TRUE))
}
col1 = myFun(100)
col2 = myFun(100)
col3 = myFun(100)
col4 = myFun(100)
group <- c("A","B","C","D")
group = sample(group, 100, replace=TRUE)
example = data.frame(col1, col2, col3, col4, group)

# 定义距离方法
method = c("osa", "lv", "dl", "hamming", "lcs", "qgram", "cosine", "jaccard", "jw","soundex")

results = list()
# 提前获取所有唯一分组,避免循环内重复计算
g = unique(example$group)
l = length(g)

for (j in 1:l) {
  # 提取当前分组数据
  current_group = g[j]
  group_data = example[example$group == current_group, ]
  
  # 初始化当前分组的结果数据框
  group_result = data.frame()
  
  for (i in 1:length(method)) {
    current_method = method[i]
    col1_col2_name = paste0("col1_col2_", current_method)
    col3_col4_name = paste0("col3_col4_", current_method)
    
    # 计算两两字符串距离并整理格式
    col1_col2_dist = stringdistmatrix(group_data$col1, group_data$col2, method = current_method, useNames = "string") %>%
      as_tibble(rownames = "a") %>%
      pivot_longer(-1, names_to = "b", values_to = col1_col2_name) %>%
      select(all_of(col1_col2_name))
    
    col3_col4_dist = stringdistmatrix(group_data$col3, group_data$col4, method = current_method, useNames = "string") %>%
      as_tibble(rownames = "a") %>%
      pivot_longer(-1, names_to = "b", values_to = col3_col4_name) %>%
      select(all_of(col3_col4_name))
    
    # 合并当前方法的结果到分组数据框
    if (i == 1) {
      group_result = cbind(col1_col2_dist, col3_col4_dist)
    } else {
      group_result = cbind(group_result, col1_col2_dist, col3_col4_dist)
    }
  }
  
  # 添加分组标识列
  group_result$group = current_group
  # 将当前分组结果加入列表
  results[[j]] = group_result
}

# 行合并所有分组的结果
final = do.call(rbind.data.frame, results)

# 验证分组分布
table(final$group)
额外说明
  1. 结果行数说明:上述代码保留了stringdistmatrix的两两比较逻辑,因此每个分组的结果行数是该分组样本数的平方(例如A分组21个样本,结果行数为21×21=441),这和你之前看到的441条A分组数据对应。
  2. 单样本距离需求:如果你只需要每个样本自身col1-col2和col3-col4的距离(而非两两比较),可以把stringdistmatrix替换为stringdist,这样结果行数和原分组样本数一致:
    col1_col2_dist = stringdist(group_data$col1, group_data$col2, method = current_method) %>%
      as.data.frame() %>%
      setNames(col1_col2_name)
    
    col3_col4_dist = stringdist(group_data$col3, group_data$col4, method = current_method) %>%
      as.data.frame() %>%
      setNames(col3_col4_name)
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 00:10:50