r - R获取并约束局部最大值位置和值的数量
问题描述
我正在使用 R 分析一些光谱,并试图获得局部最大值,即它们的位置和值。
例如,使用向量:
spectrum <- c(1,1,2,3,5,3,3,2,1,1,5,6,9,5,1,1)
我想要以下结果:
pos.peaks = c(5,13)
val.peaks = c(5,9)
我已经使用了这里提供的解决方案:Finding local maxima and minima for the position of the peaks but how to extract the对应的值?知道我不只有一个向量,我在一个列表的几个数据帧中有几列,我想将该函数应用于列表中所有数据帧的每一列。例如,对于我所做的所有职位:
example <- lapply(mylist, function (x) lapply(x, function(y) which(diff(sign(diff(y)))==-2)+1))
我没有设法使它与切片或过滤器一起使用,因为我不需要同一数据框中的相同行...
此外,我想知道如何减少我得到的局部最大值的数量,因为我的数据非常嘈杂。
我很感激你能给我的任何帮助。
谢谢!
纳特
解决方案
peakPosition <- function(x, inclBorders=TRUE) {
if(inclBorders) {y <- c(min(x), x, min(x))
} else {y <- c(x[1], x)}
y <- data.frame(x=sign(diff(y)), i=1:(length(y)-1))
y <- y[y$x!=0,]
idx <- diff(y$x)<0
(y$i[c(idx,F)] + y$i[c(F,idx)] - 1)/2
}
(pos.peaks <- peakPosition(spectrum))
#[1] 5 13
(val.peaks <- spectrum[pos.peaks])
#[1] 5 9
对于循环来获取类似的值:
example <- lapply(mylist, function(x) {x[peakPosition(x)]})
对于职位:
lapply(mylist, peakPosition)
在评论中,您说您的数据非常嘈杂,并且您达到了许多局部最大值,因此您可以先尝试平滑您的数据,如下所示:
d <- predict(loess(spectrum ~ seq_along(spectrum)))
pos.peaksS <- peakPosition(d)
(i <- pos.peaks[apply(abs(outer(pos.peaks, pos.peaksS, "-")), 1, FUN=which.min)])
#[1] 5 13
spectrum[i]
#[1] 5 9
或者您对索引进行一些聚合,例如:
set.seed(42)
x <- rnorm(1e3)
y <- peakPosition(x)
(pos.peaks <- sort(aggregate(y, list(k=kmeans(y, 7)$cluster), FUN = function(i) i[which.max(x[i])])[,2]))
#[1] 118 287 459 525 613 820 988
(val.peaks <- x[pos.peaks])
#[1] 2.701891 2.459594 2.965865 3.229069 2.223534 3.211199 3.495304
推荐阅读
- faunadb - FaunaDB:如何获取最近一小时内创建的文档?
- php - 内容有 Html 标签时如何显示限制内容
- android - 初始化问题,但已经初始化 Kotlin
- html - 防止 Chrome 中的滚动动画滞后
- python - 如何在python pptx中更改文本框中文本的字体大小
- python - rasterio 正在寻找 gdal 中不再存在的 gcs.csv
- powershell - ADuser 更改变量后未添加 samAccountName
- java - 我的根文件夹不是在 android 10 中创建的吗?
- git - git如何比较同一存储库的两个分支
- python - 为什么我会收到错误:无法在 macOS Catalina 下运行 PySide2 程序的“uic”:“execvp:没有这样的文件或目录”?