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

R语言rbind合并数据框报row.names重复错误及宽表转长表实现

报错原因

rbind()拼接数据框时强制要求行名唯一,你逐次循环取单年份子集时,每个子集都会继承原total_authority表的行号:如果原表有10行,不管取1994还是1995年的子集,行名都是1-10。第一次拼接1994年数据到空数据框不会触发问题,第二次拼接1995年数据时,两份子集行名完全重复,就会抛出你看到的重复行名错误,警告信息里列的1到10就是重复的行名值。

最优实现方案(无需编写循环)

这种多组列匹配的宽转长场景不需要写for循环,直接用tidyverse的宽转长函数一步完成即可,代码简洁不容易出错:

# 加载tidyverse包,未安装的话先运行install.packages("tidyverse")
library(tidyverse)

final_output <- total_authority %>%
  pivot_longer(
    cols = everything(),
    names_to = c(".value", "year"),
    # 按列名规则匹配国家列、得分列,按后缀区分年份
    names_pattern = "(country|score)\\.?([0-9]*)",
    values_drop_na = TRUE
  ) %>%
  mutate(
    # 把列后缀替换为实际年份值:无后缀对应1994,后缀.1对应1995
    year = case_when(
      year == "" ~ "1994",
      year == "1" ~ "1995"
    ),
    score = as.numeric(score)
  ) %>%
  # 按要求调整列顺序:国家名称、年份、指标得分
  select(country, year, score)

运行前注意两个细节:

  • 如果原表1994、1995年的得分列名不是score/score.1,只需要修改names_pattern参数里的正则,匹配你自己的得分列名即可。比如得分列叫auth_score/auth_score.1,就把正则改成"(country|auth_score)\\.?([0-9]*)"
  • 如果某一年存在缺失的国家/得分记录,values_drop_na = TRUE会自动丢弃无效行,不需要额外做缺失值过滤。
原有循环逻辑修复方案

如果要沿用你原来逐个子集拼接的思路,只需要在构建单年份子集时加上row.names = NULL参数重置行名,就能避开重复行名报错,示例代码如下:

# 初始化空结果表
final_output <- data.frame()

# 拼接1994年数据
df_1994 <- data.frame(
  country = total_authority$country,
  year = "1994",
  score = total_authority$`替换为你的1994年得分列名`,
  row.names = NULL # 核心:重置行名,避免重复
)
final_output <- rbind(final_output, df_1994)

# 拼接1995年数据
df_1995 <- data.frame(
  country = total_authority$country.1,
  year = "1995",
  score = total_authority$`替换为你的1995年得分列名`,
  row.names = NULL # 核心:重置行名,避免重复
)
final_output <- rbind(final_output, df_1995)

提示:只有两年数据的场景完全不需要写for循环,直接构建两个单年份子集拼接即可,循环逻辑反而会增加不必要的代码复杂度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 10:24:19