如何用R语言将数据框的两个出勤ID列转换为多行条目?
多列出勤ID合并为单列的R实现方法
现有一个记录事件的数据框,包含event、name1、name2三列,其中name1和name2为出勤ID列,数据构造代码如下:
event<-c(1:20) name1<-c(101:120) name2<-c(rep(NA,15),201:205) df<-data.frame(event,name1,name2)
需求是将所有出勤ID合并到单个name列中,形成每行对应一个事件与出勤ID的结构,期望结果的数据构造代码如下:
event<-c(1:16,16,17,17,18,18,19,19,20,20) name<-c(101:116,201,117,202,118,203,119,204,120,205) desired_df<-data.frame(event,name)
解决方案
方法1:使用tidyr包的pivot_longer()(推荐)
这是tidyverse生态中处理宽表转长表的常用工具,代码简洁直观:
# 首次使用需先安装包,已安装可跳过 # install.packages("tidyr") library(tidyr) result_df <- df %>% pivot_longer( cols = starts_with("name"), # 选中所有以name开头的列 names_to = "temp_col", # 临时存储原列名的列(后续会丢弃) values_to = "name", # 目标列名 values_drop_na = TRUE # 自动过滤掉NA值的行 ) %>% select(event, name) # 仅保留需要的两列
方法2:基础R的reshape()函数
如果不想依赖第三方包,可以用基础R的原生函数实现:
result_df_base <- reshape( df, direction = "long", varying = list(c("name1", "name2")), # 指定要转换的列 v.names = "name", # 目标列名 idvar = "event", # 按event分组 timevar = "temp_col" # 临时列名 ) %>% na.omit() %>% # 移除含NA的行 select(event, name) %>% arrange(event) # 按event排序,与期望结果顺序一致
两种方法最终得到的结果都与desired_df结构完全一致,可直接用于后续的数据集连接操作。
内容的提问来源于stack exchange,提问作者M3Lba
相关产品推荐
相关产品推荐

