【问题标题】:Finding local maxima/minima in R在R中找到局部最大值/最小值
【发布时间】:2012-12-28 11:52:00
【问题描述】:

我有一堆数据(每个测量系列有 10,000 - 50,000 个值),我有兴趣从这些值分布的密度估计中自动识别局部最大值/最小值。事实上,我假设通常应该有两个峰,由一个坑隔开,我想找到将两个峰彼此分开的坑,以便将数据分成两部分以进行进一步处理。如果可能的话,我也想知道山峰的位置。

由于密度估计可能包含非常小的局部变化,我希望有可能调整“灵敏度”。到目前为止我能找到的最好的是@Tommy 的这个解决方案:https://stackoverflow.com/a/6836924/1003358 这是一个例子:

library(ggplot2)

d <- density(faithful$eruptions, bw = "sj")
loc.max <- d$x[localMaxima(d$y)]

ggplot(faithful, aes(eruptions)) + geom_density(adjust=1/2) +
  geom_vline(x=loc.max, col="red") +
  xlab("Measured values")

现在,我的数据噪音更大了:

d <- density(my.df$Values, bw = "sj")
loc.max <- d$x[localMaxima(d$y)]

ggplot(my.df, aes(Values)) + geom_density(adjust=1/2) +
  geom_vline(x=loc.max, col="red") +
  xlab("Measured values")

尝试调整参数(注意发现尾部有两个“不需要”的峰):

d <- density(my.df$Values, bw="nrd", adjust=1.2)
loc.max <- d$x[localMaxima(d$y)]

ggplot(my.df, aes(Values)) + geom_density(adjust=1/2) +
  geom_vline(x=loc.max, col="red") +
  xlab("Measured values")

所以问题是:

1) 如何在如此嘈杂的数据集中自动识别真正的峰值? 2) 如何可靠地找到分隔这些峰的坑?

【问题讨论】:

  • 你如何定义“真正的高峰”?
  • @SvenHohenstein 这是个好问题。我很难从数学上掌握这个概念。峰值周围应该有一个特定的窗口,在该窗口中该峰值是最大值。此外,最小峰值大小的截止值(可能与中位数有关)可能会有所帮助。如果我知道我的数据是双峰的,则应该产生两个具有合理(我承认,这又是模糊的)大窗口的最高峰。如果我事先不知道峰值的数量,可能是最大值的截止值。将峰分开的凹坑的值以及最小值的截止值。峰值会有帮助吗?
  • 光谱数据分析(色谱或光度)经常会遇到这个问题,因此您可能会在搜索峰识别时查看是否包含“spectr*”。 @cbeleites 既是 SO 参与者,也参与了积极的 R 包开发。
  • @DWin 感谢您的建议!通过这种方式,我找到了一个名为“PROcess”的 Bioconductor 包,用于光谱处理,似乎可以产生可接受的结果。
  • 你应该发布一个简单的工作示例。

标签: r


【解决方案1】:

我最喜欢的是pastecs::turnpoints。但是你是对的,你必须做一些主观过滤来区分尖峰噪声和真正的峰值。一种方法是要求原始数据或样条数据保持在 N 个连续值的某个阈值以上。

【讨论】:

  • 感谢您的建议。 pastecs::turnpoints 似乎没有提供定义跨度/窗口的可能性,所以我再次面临与上述方法相同的问题。我不确定如何实施您的建议来定义这样的阈值。另外,据我了解,它不区分峰和坑,是吗?
  • 哦,抱歉,我刚刚注意到您可以使用extract() 方法区分峰和坑。我一定会仔细看看这个功能。但我仍然想知道过滤值的最佳方法是什么。
猜你喜欢
  • 2016-03-16
  • 2023-01-05
  • 2018-06-09
  • 2021-09-12
相关资源
最近更新 更多