提取向量中元素高于给定阈值的所有子集

Posted

技术标签:

【中文标题】提取向量中元素高于给定阈值的所有子集【英文标题】:Extract all subsets in vector where elements are above a given threshold 【发布时间】:2022-01-06 23:10:46 【问题描述】:

我想知道是否有一种 R 方式(一条线)来提取高于给定阈值的向量的所有子集的坐标。 假设我有以下数据:

v =  c(3.48, 2.59, 1.73, 0.91, 0.13, -0.63, -1.34, -2.03, -2.67, -3.28, -3.04, -2.15, -1.20, -0.19, 0.84, 1.86, 2.84, 3.77, 4.60, 5.31, 4.16, 2.87, 1.89, 0.51, 0.23, 0.78, 1.34, 2.63, 1.72, 0.62, 0.98, 1.45)

假设我有threshold = 0.7。期望的输出是:

left    right
1       4
15      23
26      29
31      32

原则上我可以编写一个while 循环或某种形式,将v 子集化并处理这些区域的leftright 坐标,例如:

left = which(subset >= threshold)[1] + right
right = which(subset[left:length(subset)] < threshold)[1] - 1 # -1 to get the last element above the threshold

subset = v[(right + 1):length(v)]

(未测试),但我确信有一种我似乎不记得的 R 方式。

我看过here,但这并不是我真正想要的。任何帮助表示赞赏。

【问题讨论】:

你是只对元素 连续间隔。像 [1,4]、[15,23] 等。 【参考方案1】:

您可以使用rle() 查找超出阈值的值的运行。当你可以把它变成你想要的格式时

rle(v>.7) |>
  with(
    data.frame(start=1, end=cumsum(lengths)) |> 
      transform(start=c(1, head(end, -1) + 1)) |> 
      subset(values)
  )

然后返回

  start end
1     1   4
3    15  23
5    26  29
7    31  32

这与 this existing question 几乎相同,主要区别在于在布尔条件上使用 rle(),然后仅将子集设置为 TRUE 值。

【讨论】:

【参考方案2】:

相同的解决方案,但使用 data.table

v =  c(3.48, 2.59, 1.73, 0.91, 0.13, -0.63, -1.34, -2.03, -2.67, -3.28, -3.04, -2.15, -1.20, -0.19, 0.84, 1.86, 2.84, 3.77, 4.60, 5.31, 4.16, 2.87, 1.89, 0.51, 0.23, 0.78, 1.34, 2.63, 1.72, 0.62, 0.98, 1.45)

data.table(v)[, .(start = .I[1], end = .I[.N], keep = unique(v > 0.7)), by = rleid(v > 0.7)][keep == T, .(start, end)]

#    start end
# 1:     1   4
# 2:    15  23
# 3:    26  29
# 4:    31  32

【讨论】:

以上是关于提取向量中元素高于给定阈值的所有子集的主要内容,如果未能解决你的问题,请参考以下文章

Excel 中 SUMPRODUCT 的问题:尝试计算高于给定阈值的平均减法数

将长向量中的元素裁剪为 +/- 阈值

使用方差阈值过滤(VarianceThreshold)进行特征选择删除方差低于某一阈值的特征详解及实战

利用 opencv实现图像自适应二值化 --python

支持向量机(SVM)之硬阈值

y_pred 的自定义损失函数 Keras 仅高于某个阈值