使用 grepl 和 dplyr 在 R 中汇总多个搜索字符串

Summarizing across multiple search strings in R using grepl and dplyr

我有一个相当杂乱无章的数据框,其中一列中的相同类别具有不同的名称。我想用 dplyr 总结那些乱七八糟的名字。

这是一个关于树种及其特性的简化数据集:

df <- data.frame(species = c('sp1', 'sp1', 'sp1', 'sp2', 'sp2'), tr = c('leaf nitrogen per mass', 'wood den', 'nitrogen (per mass)', 'leaf carbon per area', 'wood dens'), val = sample(1:10, 5), stringsAsFactors=F)

所以每个物种在这个数据集中都有许多不同类别的性状值。

您可以使用 dplyr 和下面的代码获取每个物种的汇总统计数据。

library(dplyr)
by_sp<- df %>% 
group_by(species, tr)

by_sp %>% summarize(avg = mean(val))

您可以看到它将相同的特征视为不同的,因为它们并不完全匹配。我想对许多不同特征使用模糊匹配进行总结,但不知道如何同时跨多个特征实现这一点。到目前为止,我已经尝试使用 grepl 创建一个 'required' 字符串的向量来过滤。例如

lmass <- 'nitrogen|mass'
by_sp %>% filter(grepl(lmass, tr, ignore.case=T)) %>% summarize(ave = mean(val))

但这是使用 'or',而我希望 'and'- 需要两个字符串,以便最终数据帧是包含氮和质量的所有行的单一平均值(在列 tr 中) .

此外,我有很多这样的特征字符串,我想要一个数据框,其中包含每个物种的每个特征的平均值。到目前为止,我已经尝试组合不同的搜索字符串,但这不起作用。

wood <- 'wood den' #this could have other keywords required for this trait
alltr <- c(lmass, wood)
leaf_tr %>% filter(grepl(alltr, tr, ignore.case=T)) %>% summarize(ave = mean(val)) #gives an error, only takes first element in alltr

如有任何帮助,我们将不胜感激!

这是一个data.table解决方案。我知道你在问 dplyr,但不幸的是,我 运行 解决的一些问题超出了我的 dplyr 技能(例如,使用 mutate 创建多个列):

# setup regular expressions, etc.

library(data.table); library(reshape2)    
traits <- c(nm="nitrogen.*mass", wd="wood den", ca="carbon.*area")
trait.nm <- names(traits)
DT <- data.table(df)  # make data table

DT[,  # Add a column for each trait, indicating whether row matches the trait
  c(trait.nm):=
    data.frame(sapply(trait.nm, function(x) grepl(traits[x], tr)))
]    
melt(DT, id.vars=names(df))[           # transform to long format
  value == TRUE,                       # filter for trait-val combinations that match  
  sum(val), by=.(species, variable)    # group by standardized trait
]

这会产生:

   species variable V1
1:     sp1       nm 13
2:     sp1       wd  3
3:     sp2       wd  1
4:     sp2       ca  2

注意我添加了 "Carbon Area" 类别。为了解决您的 "OR" 氮质量问题,我只是将正则表达式更改为 "nitrogen.*mass".

一个重要的警告是你需要确保每个特征只能匹配一个正则表达式,否则你最终会在不同的特征类别中多次计算该特征。