R语言数据聚合问题:按ESVId分组合并match与Form列
问题
需求:按ESVId列分组,match列保留每个唯一值并拼接;Form列保留与每个match值关联的所有值(包括重复和NA)并拼接。
原始数据集结构:
structure(list(ESVId = c("ESV_000001", "ESV_000004", "ESV_000004", "ESV_000004", "ESV_000004", "ESV_000004", "ESV_000004", "ESV_000004", "ESV_000004", "ESV_000005", "ESV_000005", "ESV_000005", "ESV_000005", "ESV_000005", "ESV_000005", "ESV_000005", "ESV_000006", "ESV_000006", "ESV_000006", "ESV_000007"), MT_species = c(1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 1, 2, 2, 1), match = c("Pseudotsuga menziesii", "Artemisia dracunculus", "Achillea millefolium", "Artemisia absinthium", "Artemisia ludoviciana", "Artemisia frigida", "Artemisia campestris", "Artemisia tridentata", "Artemisia tilesii", "Rubus arcticus", "Fragaria vesca", "Rosa acicularis", "Fragaria virginiana", "Rosa woodsii", "Rosa arkansana", "Rubus ursinus", "Poa pratensis", "Vahlodea atropurpurea", "Alopecurus magellanicus", "Prunus virginiana"), Form = c("Conifer", NA, "Forb", NA, "Forb", "Sub-Shrub", "Forb", "Shrub", NA, NA, "Forb", "Shrub", "Forb", "Shrub", NA, NA, "Graminoid", NA, NA, "Shrub")), row.names = c(NA, -20L), class = c("tbl_df", "tbl", "data.frame"))
尝试的代码:
MTTaxa_funct <- funct_esvs %>% group_by(ESVId) %>% summarise_all(funs(paste(unique(match, Form), collapse= " OR ")))%>% dplyr::select(ESVId, match, Form) %>% ungroup()
遇到的问题:运行后Form列内容与match列完全相同,且未正确保留Form列的NA值。
理想输出结构:
structure(list(ESVId = c("ESV_000001", "ESV_000004", "ESV_000005", "ESV_000006", "ESV_000007"), match = c("Pseudotsuga menziesii", "Artemisia dracunculus OR Achillea millefolium OR Artemisia absinthium OR Artemisia ludoviciana OR Artemisia frigida OR Artemisia campestris OR Artemisia tridentata OR Artemisia tilesii", "Rubus arcticus OR Fragaria vesca OR Rosa acicularis OR Fragaria virginiana OR Rosa woodsii OR Rosa arkansana OR Rubus ursinus", "Poa pratensis OR Vahlodea atropurpurea OR Alopecurus magellanicus", "Prunus virginiana"), Form = c("Conifer", "NA OR Forb OR NA OR Forb OR Sub-Shrub OR Forb OR Shrub OR NA", "NA OR Forb OR Shrub OR Forb OR Shrub OR NA OR NA", "Graminoid OR NA OR NA", "Shrub")), row.names = c(NA, -5L), class = c("tbl_df", "tbl", "data.frame" ))
解决方案
之前的代码错误在于summarise_all中使用unique(match, Form),这并非分别处理两列,而是把match和Form当作参数传给unique(),导致逻辑混乱。正确做法是分别对match和Form指定处理逻辑:
library(dplyr) MTTaxa_funct <- funct_esvs %>% group_by(ESVId) %>% summarise( # 提取match列的唯一值后拼接 match = paste(unique(match), collapse = " OR "), # 保留Form列所有值(含NA),将NA转为字符串"NA"后拼接 Form = paste(ifelse(is.na(Form), "NA", Form), collapse = " OR ") ) %>% ungroup()
代码说明:
match列:先用unique()提取分组内的唯一物种名,再用paste()拼接成指定格式的字符串。Form列:不需要去重,直接保留所有原始值;用ifelse()把NA转换为字符串"NA"(避免拼接时NA被忽略),最后完成拼接。
运行上述代码即可得到符合需求的输出。
内容的提问来源于stack exchange,提问作者sscoresby
相关产品推荐
相关产品推荐

