以来的最高值 - 找到 R 中的区间

Highest value since - finding the interval in R

我现在在外汇项目工作,途中发现了一个问题。我正在尝试查找当前值最后一次达到如此高或如此低的时间。

一开始我是这样尝试的:

length(c(1:10)) - max(which(c(1:10) <= 6))

即如果我们考虑向量 c(1:10,6),上面函数的输出将为 4。这意味着 6 是自 4 个间隔以来的最高值。

所以我现在的目标是将上述功能实现到 dplyr::mutate 方法中。这就是事情失控的地方......使用 runner 包中的 runner 函数,我能够创建带有值及其滞后的 tibble:

# A tibble: 11 x 2
   value `runner(value, lag = 1)`
   <dbl> <list>                  
 1     9 <dbl [0]>               
 2     7 <dbl [1]>               
 3     4 <dbl [2]>               
 4     1 <dbl [3]>               
 5     5 <dbl [4]>               
 6     2 <dbl [5]>               
 7     5 <dbl [6]>               
 8     4 <dbl [7]>               
 9     1 <dbl [8]>               
10     6 <dbl [9]>               
11     6 <dbl [10]>  

但是无论我尝试过什么,我都无法将当前列表中的数值编号与亚军列相关联。我正在尝试 purrr:mapsapply 之类的东西,但仍然会引用整个专栏。我也尝试实施 dplyr::rowWise 但它也没有帮助我。

我觉得我正在解决这个问题,而且很明显它很容易完成。如果有一些神奇的软件包可以帮助我快速解决我的问题,我将非常感谢您的帮助。但我仍然想知道在这种情况下是否有办法将当前行值而不是整列相关联。

我还试图将其关闭到一个整洁的用户制作的功能中,如果您能指出我的方向,那将是另一个优点。

也许您正在寻找这样的东西?

last_below <- function(x)
{
  sapply(seq(x), function(i) {
    y <- i - rev(which(x[i] >= cummax(x)))[1]
    if(y < 0) 0 else y
  })
}

所以你可以做到

library(dplyr)

df <- data.frame(x = c(1:10, 6, 4, 5, 2))
df %>% mutate(y = last_below(x))
#>     x  y
#> 1   1  0
#> 2   2  0
#> 3   3  0
#> 4   4  0
#> 5   5  0
#> 6   6  0
#> 7   7  0
#> 8   8  0
#> 9   9  0
#> 10 10  0
#> 11  6  5
#> 12  4  8
#> 13  5  8
#> 14  2 12

reprex package (v0.3.0)

于 2020-08-24 创建

runner绝对可以做到。 请注意,runner 中的 function(x) 是针对每个累积计算的 - 尝试 runner(vec) 以查看结果(列表)。想象一下,这个列表的每一个元素都是一步,每一步执行function(x)

想象一下,对于一步(例如第 10 步),您需要找到当前匹配条件之前的观察次数。

library(runner)
set.seed(1)

# dummy data
x <- round(cumsum(rnorm(10)))

current_idx <- 10
current_x <- x[current_idx]
up_to_current <- x[-current_idx]
current_idx - which(up_to_current == current_x)
# [1] 2 5

以上代码可以是 function(x) 的正文 - 当前

之前的匹配条件“很久以前”
runner(
  vec,
  function(x) {
    # current index
    current_idx <- length(x)
    
    # current value
    current_x <- x[current_idx]
    
    # values up to current
    up_to_current <- x[-current_idx]
        
    # how many observations since last condition matching 
    current_idx - which(up_to_current == current_x)       
  }  
)

上面 return 是一个列表,因为 function(x) 的输出长度不同。如果它 return 是单个值 - 它将 return 一个向量。


P.S。要找到匹配条件的索引 当前观察后,您需要包含 rev(vec) 并尝试使用索引差异。

尽情享受吧!

感谢@allan-cameron 的回答,我找到了解决方案:

last_below <- function(x) {
  sapply(
    seq(x), 
    function(i) {
      (i - tail(which(x[0:(i-1)] <= x[i]),1))[1]
    }
  )
}

通过调用:

a %>% 
  mutate(b = last_below(value)) 

我得到输出:

# A tibble: 11 x 2
   value     b
   <dbl> <int>
 1     9    NA
 2     7    NA
 3     4    NA
 4     1    NA
 5     5     1
 6     2     2
 7     5     1
 8     4     2
 9     1     5
10     6     1
11     6     1