pivot_longer() 处理多组列
我找了一些资料,但还是没搞清楚我这特定情况的语法。
我需要按下面这样的方式对数据进行分组:
library(tibble)
data_example <- tribble(
~drug_name, ~ecoli_median_molar, ~saureus_median_molar, ~ecoli_mad_molar, ~saureus_mad_molar,
"drug1", 1, 2, 0.5, 0.25,
"drug2", 4, 8, 2, 1
)
变成这样:
data_example_longer <- tribble(
~drug_name, ~pathogen, ~median, ~mad,
"drug1", "ecoli", 1, 0.5,
"drug1", "saureus", 2, 0.25,
"drug2", "ecoli", 4, 2,
"drug2", "saureus", 8, 1
)
我知道这是一种正则表达式的模式,但找不到解释语法以及如何告诉R 哪些列该放在哪里的答案。我的实际数据中病原体更多,但遵循与上面相同的模式。
解决方案
你需要的正则模式需要两个捕获组 ():一个用于病原体列名,另一个用于median|mad值:
library(tidyr)
data_example |>
pivot_longer(
cols = -drug_name,
names_to = c("pathogen", ".value"),
names_pattern = "^(pathogen\\d+)_(median|mad)_molar"
)
# A tibble: 4 × 4
# drug_name pathogen median mad
# <chr> <chr> <dbl> <dbl>
# 1 drug1 pathogen1 1 0.5
# 2 drug1 pathogen2 2 0.25
# 3 drug2 pathogen1 4 2
# 4 drug2 pathogen2 8 1
正则表达式的工作原理大致如下:
- 从列名字符串的起始处
^ (pathogen\\d+)仅在后跟一个或多个数字\\d+时,捕获字面量字符串 "pathogen"_(median|mad)_molar捕获任何在字面量 "_" 与 "_molar" 之间、且值为字面量 "median" 或 "mad" 的列
names_to = 参数中的元素,按顺序对应每个捕获组。".value" 允许你对第二个捕获组中找到的每个唯一字符串创建一个透视列。在你的情况下,与包含 "median" 或 "mad" 的列名相关的值将拥有自己的列。
基于你的评论,下面是当病原体名称变化时的一个解决方案:
data_example <- tribble(
~drug_name, ~ecoli_median_molar, ~saureus_median_molar, ~ecoli_mad_molar, ~saureus_mad_molar,
"drug1", 1, 2, 0.5, 0.25,
"drug2", 4, 8, 2, 1
)
data_example |>
pivot_longer(
cols = -drug_name,
names_to = c("pathogen", ".value"),
names_pattern = "^([^_]+)_(median|mad)_molar"
)
# # A tibble: 4 × 4
# drug_name pathogen median mad
# <chr> <chr> <dbl> <dbl>
# 1 drug1 ecoli 1 0.5
# 2 drug1 saureus 2 0.25
# 3 drug2 ecoli 4 2
# 4 drug2 saureus 8 1
唯一的差别在于第一捕获组的定义方式:
- 从列名字符串的开头
^ ([^_]+)捕获一个或多个字符+,这些字符不是下划线[^_]
其余逻辑保持不变。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。