1

我有一个相当杂乱无章的数据框,其中一列中相同类别的名称各不相同。我想用 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 创建一个“必需”字符串向量来过滤。前任。

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

但这是使用“或”,而我想要“和”- 需要两个字符串,以便最终数据帧是包含氮和质量的所有行的单个平均值(在列 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

任何帮助将非常感激!

4

1 回答 1

3

这是一个 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

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

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

于 2015-03-04T14:25:52.953 回答