使用dplyr转换不规则表格:按Name拆分Virtue为二进制列
问题描述
现有如下不规则表格:
Name Location Team Virtue Hank ABQ A Alpha Flynn ABQ B Alpha Beta Marie JFK X Gamma Beta Skylar ABQ B Alpha Beta Walter LAX D Gamma Gomie ATL A Alpha Beta Gamma Saul JFK X Beta
其中Virtue列的取值仅为Alpha、Beta或Gamma。需求是基于Name作为分组标识(Name为行分隔符),将每个Name对应的所有Virtue值转换为三列:Alpha、Beta、Gamma,用1表示该Name拥有对应Virtue,0表示没有,最终得到如下规范表格:
Name Location Team Alpha Beta Gamma Hank ABQ A 1 0 0 Flynn ABQ B 1 1 0 Marie JFK X 0 1 1 Skylar ABQ B 1 1 0 Walter LAX D 0 0 1 Gomie ATL A 1 1 1 Saul JFK X 0 1 0
请使用dplyr实现该表格转换。
解决方案
以下是使用dplyr完成转换的具体步骤和代码:
步骤说明
- 数据预处理:原始表格中存在仅
Virtue列有值的空值行,需要用前一行的Name、Location、Team值向下填充,确保每个Virtue归属到正确的分组。 - 分组聚合:按
Name、Location、Team分组,判断每组是否包含Alpha、Beta、Gamma,生成对应的二进制标识列。
代码实现
library(dplyr) library(tidyr) # 模拟读取原始不规则数据(实际场景可从文本/文件读取,此处为简化模拟) raw_data <- tibble( Name = c("Hank", "Flynn", NA, "Marie", NA, "Skylar", NA, "Walter", "Gomie", NA, NA, "Saul"), Location = c("ABQ", "ABQ", NA, "JFK", NA, "ABQ", NA, "LAX", "ATL", NA, NA, "JFK"), Team = c("A", "B", NA, "X", NA, "B", NA, "D", "A", NA, NA, "X"), Virtue = c("Alpha", "Alpha", "Beta", "Gamma", "Beta", "Alpha", "Beta", "Gamma", "Alpha", "Beta", "Gamma", "Beta") ) # 填充空值:将Name、Location、Team列的空值用前一行有效值向下填充 clean_data <- raw_data %>% fill(Name, Location, Team, .direction = "down") # 分组生成二进制列 final_table <- clean_data %>% group_by(Name, Location, Team) %>% summarize( Alpha = as.integer("Alpha" %in% Virtue), Beta = as.integer("Beta" %in% Virtue), Gamma = as.integer("Gamma" %in% Virtue), .groups = "drop" # 取消分组状态 ) # 输出结果 print(final_table, row.names = FALSE)
代码解释
fill()函数:自动填充Name、Location、Team列的空值,保证每个Virtue都对应到正确的用户分组。group_by()+summarize():按用户标识分组后,通过%in%判断当前组是否包含目标Virtue,as.integer()将布尔结果(TRUE/FALSE)转换为1/0。.groups = "drop":避免输出结果带有分组属性,生成规范的扁平表格。
内容的提问来源于stack exchange,提问作者John Thomas
相关产品推荐
相关产品推荐

