R语言双循环报错:需用.name_repair修复空列名问题
R语言分组计算字符串距离错误修复
问题背景
用户拥有如下R语言数据集:
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)
原单循环代码可计算全量数据的字符串距离指标,改为按group分组计算的双循环代码后,出现如下错误:
Error: ! Column 1 must be named. Use .name_repair to specify repair. Caused by error in `repaired_names()`: ! Names can't be empty. x Empty name found at location 1.
用户编写的错误双循环代码:
results = list() for (i in 1:length(method)) for (j in 1:length(unique(example$group)) { { groups_j = unique(example$group[j]) my_data_i = file[which(file$fsa == groups_j ), ] method_i = method[i] name_1_i = paste0("col1_col_2", method_i) name_2_i = paste0("col3_col_4", method_i) p1_i = stringdistmatrix(my_data_i$col1, my_data_i$col2, method = method_i, useNames = "string") %>% as_tibble(rownames = "a") %>% pivot_longer(-1, names_to = "b", values_to = name_1_i) p2_i = stringdistmatrix(my_data_i$col3, my_data_i$col4, method = method_i, useNames = "string") %>% as_tibble(rownames = "a") %>% pivot_longer(-1, names_to = "b", values_to = name_2_i) p1_i = p1_i[,3] p2_i = p2_i[,3] final_i = cbind(p1_i, p2_i) results[[i]] = final_i } } final = do.call(cbind.data.frame, results) final = cbind(col1,col2, col3,col4, final) average_col1_col2_dist = (final$col1_col_2osa + final$col1_col_2lv + final$col1_col_2dl + final$col1_col_2hamming + final$col1_col_2lcs + final$col1_col_2qgram + final$col1_col_2cosine + final$col1_col_2jaccard + final$col1_col_2jw + final$col1_col_2soundex)/10 average_col3_col4_dist = ( final$col3_col_4osa + final$col3_col_4lv + final$col3_col_4dl + final$col3_col_4hamming + final$col3_col_4lcs + final$col3_col_4qgram + final$col3_col_4cosine + final$col3_col_4jaccard + final$col3_col_4jw + final$col3_col_4soundex)/10 final = data.frame( col1, col2, col3, col4, average_col1_col2_dist, average_col3_col4_dist) final = scale(final)
错误原因分析
- 循环语法缺失:第二个
for循环末尾未加闭合括号,导致代码结构混乱。 - 变量引用错误:使用了不存在的
file对象(应为example),且错误引用fsa列(实际是group列)。 - 分组提取逻辑错误:
unique(example$group[j])无法正确获取分组,应该直接遍历唯一分组值而非索引。 - 结果存储覆盖:双循环中仅用
results[[i]]存储,会覆盖同一方法下不同分组的结果,导致数据结构异常。 - 列名丢失问题:
p1_i = p1_i[,3]这类操作会移除列名,后续合并时出现空列名触发报错。
修复后的完整代码
library(stringdist) library(tidyverse) method = c("osa", "lv", "dl", "hamming", "lcs", "qgram", "cosine", "jaccard", "jw","soundex") # 初始化结果列表,按"分组_方法"命名存储 results <- list() # 获取所有唯一分组 unique_groups <- unique(example$group) # 双循环:外层遍历分组,内层遍历距离计算方法 for (j in seq_along(unique_groups)) { current_group <- unique_groups[j] # 提取当前分组的数据集 group_data <- example %>% filter(group == current_group) for (i in seq_along(method)) { current_method <- method[i] # 定义列名,避免格式混乱 col1_col2_name <- paste0("col1_col2_", current_method) col3_col4_name <- paste0("col3_col4_", current_method) # 计算col1与col2的字符串距离矩阵,整理为长格式 dist_col1_col2 <- stringdistmatrix(group_data$col1, group_data$col2, method = current_method, useNames = "string") %>% as_tibble(rownames = "col1_val") %>% pivot_longer(-col1_val, names_to = "col2_val", values_to = col1_col2_name) # 计算col3与col4的字符串距离矩阵,整理为长格式 dist_col3_col4 <- stringdistmatrix(group_data$col3, group_data$col4, method = current_method, useNames = "string") %>% as_tibble(rownames = "col3_val") %>% pivot_longer(-col3_val, names_to = "col4_val", values_to = col3_col4_name) # 合并当前方法的结果,添加分组标识 combined_data <- bind_cols(dist_col1_col2, dist_col3_col4) %>% mutate(group = current_group) # 按"分组_方法"命名存储到列表 results[[paste0(current_group, "_", current_method)]] <- combined_data } } # 合并所有分组+方法的结果 full_results <- bind_rows(results) # 计算每组内的平均距离 average_results <- full_results %>% group_by(group, col1_val, col2_val, col3_val, col4_val) %>% summarise( average_col1_col2_dist = mean(c_across(starts_with("col1_col2_"))), average_col3_col4_dist = mean(c_across(starts_with("col3_col4_"))), .groups = "drop" ) # 仅对数值型的平均距离列做标准化处理 scaled_results <- average_results %>% mutate(across(c(average_col1_col2_dist, average_col3_col4_dist), scale))
关键修复说明
- 修正循环结构:补全循环括号,调整为外层遍历分组、内层遍历方法的逻辑,契合分组计算需求。
- 修复变量引用:将
file改为example,fsa改为group,确保数据提取正确。 - 保留列名完整性:移除
p1_i = p1_i[,3]这类丢失列名的操作,后续通过starts_with精准匹配列进行均值计算。 - 避免数据覆盖:用
分组_方法作为列表元素名称,确保不同分组的结果独立存储,最后通过bind_rows合并。 - 规范均值计算:使用
c_across+mean替代手动求和除以10,代码更简洁且不易出错。 - 正确标准化:仅对数值型的平均距离列执行
scale操作,避免对字符串列做无效处理。
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

