如何使用R语言将含重复vote/name列的表格转换为指定结构?
R语言实现重复列结构表格的规范重塑
需求说明
将表头为city、vote、name、vote、name、vote、name的重复列结构表格,转换为以city为第一列,name1/name2/name3为列名、对应单元格为该城市对应name的vote值的规范宽表。
最优实现方案(Tidyverse 管道式)
使用tidyverse包的pivot_longer和pivot_wider组合是最清晰、易维护的方案,适配R自动为重复列名添加的后缀(如vote.1、name.2)。
步骤1:构造示例原数据
library(tidyverse) # 模拟用户描述的重复列名表格 original_df <- tibble( city = c("c1", "c2"), `vote` = c(83, 45), # c1的name2得票83,c2的name1得票45 `name` = c("name2", "name1"), `vote` = c(17, 30), # c1的name1得票17,c2的name2得票30 `name` = c("name1", "name2"), `vote` = c(5, 25), # c1的name3得票5,c2的name3得票25 `name` = c("name3", "name3") )
步骤2:执行重塑操作
target_df <- original_df %>% # 将所有非city列按vote/name分组转成长格式 pivot_longer( cols = -city, names_to = c(".value", "group"), # 匹配列名中的vote/name前缀,以及R自动添加的后缀(如.1/.2) names_pattern = "(vote|name)(\\.*\\d*)" ) %>% # 清理分组标记中的多余点号 mutate(group = str_remove(group, "^\\.")) %>% # 转成目标宽格式:city为行标识,name为列,vote为单元格值 pivot_wider( id_cols = city, names_from = name, values_from = vote ) # 查看结果 print(target_df)
输出结果
# A tibble: 2 × 4 city name1 name2 name3 <chr> <dbl> <dbl> <dbl> 1 c1 17 83 5 2 c2 45 30 25
备选Base R方案(仅作参考)
若无法使用tidyverse,可通过reshape函数实现,但可读性和灵活性较差:
# 手动重命名重复列 colnames(original_df) <- c("city", paste0(c("vote_", "name_"), rep(1:3, each=2))) # 转长格式 long_df <- reshape(original_df, direction = "long", varying = -1, sep = "_") # 转宽格式 target_df_base <- reshape(long_df, direction = "wide", idvar = "city", timevar = "name") # 清理列名 colnames(target_df_base) <- gsub("vote\\.", "", colnames(target_df_base))
方案优势
- Tidyverse方案通过管道式操作逻辑清晰,代码可扩展性强(新增vote/name对无需大幅修改)
names_pattern自动适配R对重复列名的命名规则,无需手动重命名- 输出结果完全符合需求的规范宽表结构
内容的提问来源于stack exchange,提问作者Teddy
相关产品推荐
相关产品推荐

