如何在R中使用dplyr/tidyverse将分组行转换为列?
解决方案:按
hid分组扩展tmid和thid为列 我来帮你解决这个问题,你需要的是按hid分组后,把tmid和thid根据mid扩展成列,并且同一分组下的对应列值保持一致,缺失值用0填充。这里有一个基于dplyr和tidyr的可行方案:
步骤说明
- 先为每个
hid生成完整的mid序列(覆盖到你提到的最大可能值8),填充缺失的tmid和thid为0; - 将分组后的完整数据转换为宽格式,生成
tmid1/thid1这类命名的列; - 把原数据和分组后的宽表进行左连接,让每一行都带上对应
hid的所有扩展列。
完整代码
library(dplyr) library(tidyr) # 定义mid的最大可能值(根据你的需求设为8) max_mid <- 8 # 先处理因子类型(如果你的tmid/thid是因子,先转成字符避免水平问题) df <- df %>% mutate(across(c(tmid, thid), as.character)) # 第一步:为每个hid生成完整的mid序列,填充缺失值为0,并转成宽格式 hid_wide <- df %>% group_by(hid) %>% # 生成1到max_mid的所有mid值,补全缺失的mid complete(mid = 1:max_mid) %>% # 将NA替换为"0" mutate(across(c(tmid, thid), ~replace_na(.x, "0"))) %>% # 转换为宽格式,生成tmid1、thid1这样的列名 pivot_wider( id_cols = hid, names_from = mid, values_from = c(tmid, thid), names_glue = "{.name}{mid}" ) %>% ungroup() # 第二步:连接原数据和分组宽表,得到最终结果 result <- df %>% left_join(hid_wide, by = "hid") # 查看结果 print(result)
代码解释
complete(mid = 1:max_mid):确保每个hid下都包含从1到8的所有mid值,不会遗漏任何需要扩展的列;replace_na(.x, "0"):把补全后缺失的tmid/thid值替换为0,满足你的填充要求;pivot_wider:用names_glue参数生成符合要求的列名(比如tmid+mid得到tmid1);- 左连接操作保证原数据的每一行都能带上对应
hid的所有扩展列,并且同一hid下的扩展列值完全一致。
结果验证
以你提供的示例数据为例,处理后hid=2的所有行都会带上tmid1=010、tmid2=0120、tmid3=010、tmid4=010、tmid5=020、tmid6=0...tmid8=0,对应的thid列也会按同样规则填充,完全符合你期望的输出格式。
内容的提问来源于stack exchange,提问作者HSJ
相关产品推荐
相关产品推荐

