在R中根据条件生成含列名的新列:宽转长数据处理需求
解决方案:宽格式陪伴数据转长格式并合并陪伴者信息
核心思路
用 tidyverse 工具链完成转换:先给每行标记参与者ID,将宽格式数据转为长格式,拆分列名提取关键信息,最后按「参与者+日期+时段」分组合并所有标记为'yes'的陪伴者。
具体代码实现
假设你的原始数据框名为raw_data,代码如下:
library(tidyverse) # 1. 添加参与者ID列(每行对应一位参与者) processed_data <- raw_data %>% mutate(Participant = row_number()) # 若原数据有自定义行名,可改用 rownames_to_column("Participant") # 2. 转换为长格式:将所有列转为「列名(name)」和「值(value)」两列 processed_data <- processed_data %>% pivot_longer( cols = -Participant, # 排除参与者ID列,其余列转成long格式 names_to = "col_name", values_to = "status" ) # 3. 只保留status为'yes'的记录(no/n/a无意义,直接过滤) processed_data <- processed_data %>% filter(status == "yes") # 4. 拆分列名提取Day、Hour、陪伴者类型和编号,生成SpentWith列 processed_data <- processed_data %>% separate( col = col_name, into = c("Day", "Hour", "Type", "Number"), sep = "\\.", # 按点号拆分,注意转义 remove = FALSE # 可选:保留原列名用于后续校验 ) %>% mutate( SpentWith = str_c(str_to_title(Type), Number), # 将adult.1转为Adult1格式 Hour = str_replace(Hour, "\\.00$", "") # 可选:把06.00简化为06,或转成时间格式 ) # 5. 按参与者、日期、时段分组,合并所有陪伴者 final_data <- processed_data %>% group_by(Participant, Day, Hour) %>% summarise( SpentWith = str_c(SpentWith, collapse = ", "), # 用逗号分隔合并多个陪伴者 .groups = "drop" # 取消分组状态 )
关键说明
- pivot_longer:解决了你之前无法关联参与者的问题,转换时会保留每行的Participant ID,确保每个'yes'记录都能对应到正确的参与者。
- separate:精准拆分列名中的结构化信息,避免手动提取列名的混乱。
- summarise + str_c:替代case_when,直接分组合并同一时段的所有陪伴者,简洁高效。
大型数据优化方案
如果数据量极大(上万行+1300列),可以用data.table提升处理速度,逻辑与tidyverse一致:
library(data.table) setDT(raw_data) raw_data[, Participant := .I] # 添加参与者ID long_data <- melt(raw_data, id.vars = "Participant", variable.name = "col_name", value.name = "status") long_data <- long_data[status == "yes"] long_data[, c("Day", "Hour", "Type", "Number") := tstrsplit(col_name, "\\.")] long_data[, SpentWith := paste0(toupper(substr(Type, 1, 1)), substr(Type, 2, nchar(Type)), Number)] final_data <- long_data[, .(SpentWith = paste(SpentWith, collapse = ", ")), by = .(Participant, Day, Hour)]
内容的提问来源于stack exchange,提问作者EmmaV97
相关产品推荐
相关产品推荐

