【问题标题】:For each value in a vector get the corresponding next smallest value对于向量中的每个值,获取相应的下一个最小值
【发布时间】:2022-01-07 06:57:03
【问题描述】:

对于向量中的每个元素,我想要向量中对应的下一个较小的值,而不改变元素的原始顺序。

例如,假设给定的向量是:

c(4, 5, 5, 10, 3, 7)

那么结果就是:

c(3, 4, 4, 7, 0, 5)

请注意,由于 3 没有任何更小的值,我希望将其替换为 0。 任何帮助都感激不尽。谢谢。

【问题讨论】:

    标签: r vector lag


    【解决方案1】:

    我们可能会使用

    sapply(v1, function(x) sort(v1)[match(x, sort(v1))-1][1])
    [1]  3  4  4  7 NA  5
    

    或者使用矢量化选项

    v2 <- unique(v1)
    v3 <- sort(v2)
    v4 <-  v3[-length(v3)]
    i1 <- match(v1, v3) - 1
    i1[i1 == 0] <- NA
    v4[i1]
    [1]  3  4  4  7 NA  5
    

    数据

    v1 <- c(4, 5, 5, 10, 3, 7)
    

    【讨论】:

    • 感谢@akrun 的快速回复。这实际上工作得很好,但我有一个大小为 50000 的冗长向量,所以 sapply 需要一段时间才能给我答案。有没有办法让它更快一点或者没有 sapply?谢谢
    • @LindaA 更新对你有用吗?
    • 更新后的方法运行得非常快@akrun。谢谢。
    【解决方案2】:

    我们可以使用outer + max.col试试下面的代码

    > m <- outer(v, u <- sort(unique(v)), `>`)
    
    > replace(u[max.col(m, ties.method = "last")], rowSums(m) == 0, NA)
    [1]  3  4  4  7 NA  5
    

    【讨论】:

    • 这也可以,但比@akrun 更新的要慢一些
    • @LindaA 是的,它很慢,尤其是当你有很大的v 由于outer
    【解决方案3】:

    使用findInterval

    sx = sort(x)
    i = findInterval(x, sx, left.open = TRUE)
    sx[replace(i, i == 0, NA)]
    # [1]  3  4  4  7 NA  5
    

    【讨论】:

    • 有趣的findInterval 解决方案,+1!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-19
    • 1970-01-01
    • 2016-02-27
    • 1970-01-01
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多