You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用pivot_longer()将多组结构化列转换为长格式数据

如何使用pivot_longer()将多组结构化列转换为长格式数据

嘿,这个问题我处理类似实验数据时也碰到过!用tidyr包的pivot_longer()完全能轻松搞定,尤其是你这种同一病原体对应多组指标列的结构化数据,核心就是用好names_to和names_pattern这两个参数,我给你一步步讲明白:

首先先理清楚你的数据规律:原始列名都是[病原体]_[指标]_molar的结构,比如ecoli_median_molar里,ecoli是病原体,median是指标,_molar是固定后缀。我们要做的就是把列名拆成病原体和指标两部分,再把指标对应的值映射到新的列中。

直接上可用的代码,你可以直接套用到自己的数据上:

library(tibble)
library(tidyr)

# 你的示例原始数据
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 <- data_example %>%
  pivot_longer(
    cols = -drug_name,  # 保留drug_name作为标识符,转换其他所有列
    names_to = c("pathogen", ".value"),  # 列名拆分规则
    names_pattern = "(.*)_(.*)_molar"  # 正则匹配列名结构
  )

我给你拆解下每个参数的作用,这样你以后改起来也方便:

  • cols = -drug_name:明确告诉R,除了drug_name列要保留原样,其他所有列都需要被转换成长格式。
  • names_to = c("pathogen", ".value"):这是最关键的部分:
    • "pathogen":列名中匹配到的第一部分(病原体名称)会被放到这个新创建的列里;
    • ".value":这是pivot_longer()的特殊占位符,意思是“把列名里的这部分作为新的列名”——也就是这里的median和mad会成为新的列,对应的值会自动填充到对应的行里。
  • names_pattern = "(.*)_(.*)_molar":正则表达式的分组匹配:
    • 第一个(.*):匹配第一个_之前的所有字符(比如ecoli、saureus);
    • 第二个(.*):匹配两个_之间的字符(比如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   

另外给你提个小醒:如果你的真实数据里列名的后缀不是_molar,只要调整names_pattern里的最后部分就行。比如如果后缀是_conc,就把正则改成"(.*)_(.*)_conc",完全不影响对病原体和指标的匹配。

备注:内容来源于stack exchange,提问作者Teagan P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 18:02:58