当前位置: 首页 > 知识库问答 >
问题:

指定值的最近后续索引

计向晨
2023-03-14

考虑向量:

int = c(1, 1, 0, 5, 2, 0, 0, 2)

我想得到指定值的最近的后续索引(而不是差异)。函数的第一个参数应该是向量,而第二个参数应该是希望看到最近的后续元素的值。

例如,

f(int, 0)
# [1] 2 1 0 2 1 0 0 NA

这里,向量(1)的第一个元素是远离第一个后续0, (3 - 1 = 2)的两个位置,因此它应该返回2。然后第二个元素距离0 (2 - 1 = 1)1个位置。当没有与指定值匹配的后续值时,返回NA(这里是最后一个元素的情况,因为没有后续值是0)。

其他例子:

f(int, 1)
# [1] 0 0 NA NA NA NA NA NA

f(int, 2) 
# [1] 4 3 2 1 0 2 1 0

f(int, 3) 
# [1] NA NA NA NA NA NA NA NA

这也应该适用于字符向量:

char = c("A", "B", "C", "A", "A")

f(char, "A") 
# [1] 0 2 1 0 0

共有3个答案

齐高寒
2023-03-14

使用序列

f <- function(v, x){
  d = diff(c(0, which(v == x)))
  vec <- sequence(d, d-1, by = -1)
  length(vec) <- length(int)
  vec
}

输出

int = c(1, 1, 0, 5, 2, 0, 0, 2)
char = c("A", "B", "C", "A", "A")

f(int, 0)
# [1]  2  1  0  2  1  0  0 NA

f(int, 1)
# [1]  0  0 NA NA NA NA NA NA

f(int, 2)
# [1] 4 3 2 1 0 2 1 0

f(char, "A")
# [1] 0 2 1 0 0

基准(n=1000):

set.seed(123)
int = sample(0:100, size = 1000, replace = T)

library(microbenchmark)
bm <- microbenchmark(
  fSequence(int, 0),
  fzx8754(int, 0),
  fRecursive(int, 0), 
  fMartinMorgan(int, 0), 
  fMap2dbl(int, 0),
  fReduce(int, 0),
  fAve(int, 0),
  fjblood94(int, 0),
  times = 10L,
  setup = gc(FALSE)
)
autoplot(bm)

使用的功能

fSequence <- function(v, x){
  vec <- sequence(diff(c(0, which(v == x))), diff(c(0, which(v == x))) - 1, by = -1)
  length(vec) <- length(v)
  vec
}

fzx8754 <- function(v, x){
  sapply(seq_along(v), function(i){
    which(v[ i:length(v) ] == x)[ 1 ] - 1
  })
}

fRecursive <- function(lookup,val ) {
  ind <- which(lookup == val)[1] -1
  if (length(lookup) > 1) {
    c(ind, f(lookup[-1], val))
  } else {
    ind
  }
}

fMartinMorgan <- function(x, value) {
  idx = which(x == value)
  nearest = rep(NA, length(x))
  nearest[1:max(idx)] = rep(idx, diff(c(0, idx)))
  abs(seq_along(x) - nearest)
}

fMap2dbl <- function(int, num)
{
  n <- length(int)
  
  map2_dbl(num, 1:n, ~ ifelse(length(which(.x == int[.y:n])) == 0, NA, 
                              min(which(.x == int[.y:n])) - 1))
}

fReduce <- function(vec, value) {
  replace(
    Reduce(
      function(x, y)
        x  + (y * x) ,
      vec != value,
      right = TRUE,
      accumulate = TRUE
    ),
    max(tail(which(vec == value), 1), 0) < seq_along(vec),
    NA
  )
}

fAve <- function(init, k) {
  ave(
    seq_along(init),
    c(0, head(cumsum(init == k), -1)),
    FUN = function(x) if (any(x == k)) rev(seq_along(x) - 1) else NA
  )
}

fjblood94 <- function(v, val) {
  out <- integer(length(v))
  if (v[length(v)] != val) out[length(v)] <- NA_integer_
  
  for (i in (length(v) - 1L):1) {
    if (v[i] == val) {
      out[i] <- 0L
    } else {
      out[i] <- out[i + 1L] + 1L
    }
  }
  
  return(out)
}

鲁鸿朗
2023-03-14

查找从第n个位置到向量末尾的匹配,然后获得第一个匹配:

f <- function(v, x){
  sapply(seq_along(v), function(i){
    which(v[ i:length(v) ] == x)[ 1 ] - 1
  })
}

f(int, 0)
# [1]  2  1  0  2  1  0  0 NA
f(int, 1)
# [1]  0  0 NA NA NA NA NA NA
f(int, 2)
# [1] 4 3 2 1 0 2 1 0
f(int, 3) 
# [1] NA NA NA NA NA NA NA NA

f(char, "A") 
# [1] 0 2 1 0 0
姬高扬
2023-03-14

查找每个值(数字或字符)的位置

int = c(1, 1, 0, 5, 2, 0, 0, 2)
value = 0
idx = which(int == value)
## [1] 3 6 7

int中最后一个值之后使用NA展开索引以指示最近的感兴趣值。

nearest = rep(NA, length(int))
nearest[1:max(idx)] = rep(idx, diff(c(0, idx))),
## [1]  3  3  3  6  6  6  7 NA

使用简单算法找出当前值的索引和最近值的索引之间的差异

abs(seq_along(int) - nearest)
## [1]  2  1  0  2  1  0  0 NA

作为函数编写

f <- function(x, value) {
    idx = which(x == value)
    nearest = rep(NA, length(x))
    if (length(idx)) # non-NA values only if `value` in `x`
        nearest[1:max(idx)] = rep(idx, diff(c(0, idx)))
    abs(seq_along(x) - nearest)
}

我们有

> f(int, 0)
[1]  2  1  0  2  1  0  0 NA
> f(int, 1)
[1]  0  0 NA NA NA NA NA NA
> f(int, 2)
[1] 4 3 2 1 0 2 1 0
> f(char, "A")
[1] 0 2 1 0 0
> f(char, "B")
[1]  1  0 NA NA NA
> f(char, "C")
[1]  2  1  0 NA NA

该解决方案不涉及递归或R级循环,因此即使对于长向量也应该快速。

 类似资料:
  • 当我查看注册表仪表板时,当结束时,我会看到以下警告消息: 当我查看代码时,测试始终为true 为什么是默认配置,它似乎怪异,因为它不断地产生一个警告! 如果有谁能给我一个解释。我想我错过了什么…

  • 问题内容: 我想在逻辑范围内生成一个随机整数。因此,举例来说,我正在编写一个程序来“掷掷”具有指定边数的骰子。 现在的问题是,它将返回边与零之间的值, 包括 0和0,这是没有意义的,因为大多数骰子从1到6、9等。因此,我如何指定nextInt应该在1和边数之间起作用? 问题答案: 要在 from 和 to (包括)之间生成一个随机的int值(均匀分布),请使用: 以您的情况(1 ..面):

  • 我在尝试从时间戳查找数据中的值时出错。我的df有一个时间戳索引。 我的时间戳是: 我的df索引是这样的: 使用index.get_loc函数: 错误是: 我看到这个错误可能来自于数据帧的串联和索引的冲突,但这里的情况并非如此。有什么想法吗?

  • 在Google Sheets中,我试图使用Excel中的索引匹配返回与日期范围之间最小绝对最近值关联的帐户名。 以下是数据值: A列是评估的日期范围 以下是一些虚拟数据的示例: 现在这个公式起作用了。。。索塔。它将返回与最小绝对最近值关联的帐户名,但不从以下指定的日期范围返回: 这是返回帐户“A”,因为它是第一个值,最接近猜测值,但它超出了G2和G3指定的日期范围。 从这个例子中应该返回的正确答案

  • 我需要将浮点值四舍五入为最接近的整数,就像值为 如果我的价值是 我使用的方法是圆()、地()和固定(),但它只起、下、等号。

  • 返回指定值应插入到数组中的最低索引位置,以保持其排序顺序。 检查数组是否按降序(松散地)排序。 使用 Array.findIndex() 来找到元素应该被插入的合适的索引位置。 const sortedIndex = (arr, n) => { const isDescending = arr[0] > arr[arr.length - 1]; const index = arr.find