在R语言中实现多列数据的宽表转长表(Pivot)
宽格式转长格式:pivot_longer的正确用法
首先,你的宽格式数据如下:
df_wide <- data.frame( name = c("John", "Smith", "Tom", "Alice"), area = c("A", "A", "B", "B"), hello_1 = c(20, 30, 40, 70), hello_covered = c(60, 89, 76, 87), world_1 = c(55, 65, 20, 29), world_1_covered = c(87, 29, 43, 42) )
要转换成你期望的长格式,关键是利用pivot_longer的正则分组功能,匹配列名中的前缀(hello/world)和后缀(1/covered),具体代码如下:
library(tidyr) df_long <- df_wide %>% pivot_longer( cols = -c(name, area), # 保留name和area列,转换其余所有列 names_pattern = "(\\w+)_(1|covered)", # 将列名拆分为两个分组:药品名称、值类型 names_to = c("medicine", ".value") # 第一组内容存入medicine列,第二组作为值对应的列名 ) %>% rename(value = `1`) # 将自动生成的`1`列重命名为value
运行后得到的结果完全符合你的期望:
> df_long # A tibble: 8 × 5 name area medicine value covered <chr> <chr> <chr> <dbl> <dbl> 1 John A hello 20 60 2 John A world 55 87 3 Smith A hello 30 89 4 Smith A world 65 29 5 Tom B hello 40 76 6 Tom B world 20 43 7 Alice B hello 70 87 8 Alice B world 29 42
关键参数说明
cols = -c(name, area):明确指定不需要转换的列,避免手动列举所有需要转换的列names_pattern:用正则表达式拆分列名,(\\w+)匹配hello/world这类前缀,(1|covered)匹配后缀的两种类型names_to = c("medicine", ".value"):.value是特殊参数,表示将第二组的内容作为值列的名称,这样hello_1的值会进入1列,hello_covered的值进入covered列- 最后用
rename把1列改成更直观的value
内容的提问来源于stack exchange,提问作者unaeem
相关产品推荐
相关产品推荐

