如何对列名含序号后缀的DataFrame执行Pivot Longer操作?
解决方案
你可以用tidyr包的pivot_longer()函数处理这种带后缀的宽格式数据,或者用基础R方法实现,两种方式如下:
方法一:使用tidyr(推荐)
利用正则表达式匹配列名的固定前缀和可变后缀,直接转换为长格式:
library(tidyr) # 原始数据 df <- structure(list(Name = "Jon", Age = 23, Name1 = "Jessica", Age1 = 13, Name2 = "Martin", Age2 = 54), class = "data.frame", row.names = c(NA, -1L)) # 转换格式 result <- df %>% pivot_longer( cols = everything(), names_to = c(".value", "id"), # .value保留前缀作为新列名,id存储后缀数字 names_pattern = "(Name|Age)(\\d*)" # 捕获前缀和后缀 ) %>% select(-id) # 移除临时的id列 print(result)
执行后输出:
# A tibble: 3 × 2 Name Age <chr> <dbl> 1 Jon 23 2 Jessica 13 3 Martin 54
关键参数说明:
names_to = c(".value", "id"):.value是特殊占位符,将列名的固定部分(Name/Age)作为新列名;id临时存储列名的数字后缀。names_pattern = "(Name|Age)(\\d*)":正则表达式,(Name|Age)匹配列名前缀,(\\d*)匹配后续的数字(允许空值,对应原始的Name和Age列)。
方法二:基础R实现
通过提取姓名和年龄列组,再合并为长格式:
# 原始数据 df <- structure(list(Name = "Jon", Age = 23, Name1 = "Jessica", Age1 = 13, Name2 = "Martin", Age2 = 54), class = "data.frame", row.names = c(NA, -1L)) # 提取姓名和年龄列 name_cols <- grep("^Name", names(df), value = TRUE) age_cols <- grep("^Age", names(df), value = TRUE) # 合并为结果数据框 result_base <- data.frame( Name = unlist(df[name_cols]), Age = unlist(df[age_cols]), stringsAsFactors = FALSE ) # 重置行名 rownames(result_base) <- 1:nrow(result_base) print(result_base)
执行后输出:
Name Age 1 Jon 23 2 Jessica 13 3 Martin 54
内容的提问来源于stack exchange,提问作者Jamie
相关产品推荐
相关产品推荐

