【问题标题】:Assigning unique identifier to consecutive sequences of binomial values in R [duplicate]为R中的连续二项式值序列分配唯一标识符
【发布时间】:2021-05-14 13:12:12
【问题描述】:

我有一个数据框,其列由 0 和 1 的序列组成。 0 不感兴趣,但 1 表示在时间序列中发生的事件,目标是为每个事件分配唯一的值。简单的整数值就足够了。所以在下面的代码中,“x”是我所拥有的,“目标”是我所追求的。

这看起来很简单,但我不知道如何在帮助搜索中表达这个问题......

我拥有的数据框:

x <- c(rep(0,4),rep(1,5),rep(0,2),rep(1,4),rep(0,10),rep(1,3))

x <- data.frame(x)

我想要的数据框:

x$goal <- c(rep(0,4),rep(1,5),rep(0,2),rep(2,4),rep(0,10),rep(3,3))

【问题讨论】:

    标签: r sequence seq run-length-encoding


    【解决方案1】:

    这实际上是一种游程编码,带有轻微的扭曲(零化0s)。

    虽然data.table::rleid 做得很好,但如果您还没有使用该软件包,那么我们将使用

    my_rleid <- function(x) { yy <- rle(x); rep(seq_along(yy$lengths), yy$lengths); }
    

    从这里,我们会看到

    x$out <- my_rleid(x$x)
    x$out <- ifelse(x$x == 0, 0L, x$out)
    x
    #    x goal out
    # 1  0    0   0
    # 2  0    0   0
    # 3  0    0   0
    # 4  0    0   0
    # 5  1    1   2
    # 6  1    1   2
    # 7  1    1   2
    # 8  1    1   2
    # 9  1    1   2
    # 10 0    0   0
    # 11 0    0   0
    # 12 1    2   4
    # 13 1    2   4
    # 14 1    2   4
    # 15 1    2   4
    # 16 0    0   0
    # 17 0    0   0
    # 18 0    0   0
    # 19 0    0   0
    # 20 0    0   0
    # 21 0    0   0
    # 22 0    0   0
    # 23 0    0   0
    # 24 0    0   0
    # 25 0    0   0
    # 26 1    3   6
    # 27 1    3   6
    # 28 1    3   6
    

    这非常接近。如果你需要连续的数字(没有像上面那样的空白),那么

    x$out <- match(x$out, sort(unique(x$out))) - (0 %in% x$out)
    x
    #    x goal out
    # 1  0    0   0
    # 2  0    0   0
    # 3  0    0   0
    # 4  0    0   0
    # 5  1    1   1
    # 6  1    1   1
    # 7  1    1   1
    # 8  1    1   1
    # 9  1    1   1
    # 10 0    0   0
    # 11 0    0   0
    # 12 1    2   2
    # 13 1    2   2
    # 14 1    2   2
    # 15 1    2   2
    # 16 0    0   0
    # 17 0    0   0
    # 18 0    0   0
    # 19 0    0   0
    # 20 0    0   0
    # 21 0    0   0
    # 22 0    0   0
    # 23 0    0   0
    # 24 0    0   0
    # 25 0    0   0
    # 26 1    3   3
    # 27 1    3   3
    # 28 1    3   3
    

    我选择使用- (0 %in% x$out) 而不是硬编码的1 的原因是我想防止数据中没有0 的可能性。换句话说,(0 %in% x$out) 解析为FALSETRUE,当从integers 中减去时,将分别强制转换为0L1L。我需要这个的原因:如果在$out 中有一个0,那么match 将实际上是match(0, 0:6),它将返回1。我们希望x == 0 匹配为0L,所以我们必须减去一个。由于第二个参数(来自 sort(unique(.)))总是从 0 开始(如此处)或从 1 开始(x$x 中不存在零),因此很容易调整。

    如果您确定不是这种情况,并且您不喜欢我附加到match(.)- (.),那么您可以将其更改为match(.) - 1L

    【讨论】:

    • 哇,谢谢!效果很好,我很欣赏使用基本命令这样做的能力。
    • 您也可以只使用rle 对象:r = rle(x != 0); r$values = cumsum(r$values) * r$values; inverse.rle(r)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多