如何使用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
相关产品推荐
相关产品推荐

