使用 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"
.
一个重要的警告是你需要确保每个特征只能匹配一个正则表达式,否则你最终会在不同的特征类别中多次计算该特征。
我有一个相当杂乱无章的数据框,其中一列中的相同类别具有不同的名称。我想用 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"
.
一个重要的警告是你需要确保每个特征只能匹配一个正则表达式,否则你最终会在不同的特征类别中多次计算该特征。