gpt4 book ai didi

r - 填充两个指定值之间的所有条目

转载 作者:行者123 更新时间:2023-12-04 22:56:22 27 4
gpt4 key购买 nike

我有一个很长的向量,有数千个条目,其中偶尔包含 0、1、2 元素。 0 表示“无信号”,1 表示“信号开启”,2 表示“信号关闭”。我试图找到从 1 到下一次出现的 2 的运行,并用 1 填充空间。我还需要在 2 和下一次出现的 1 之间做同样的事情,但用 0 填充空间。

我目前有一个使用循环来解决这个问题的解决方案,但它很慢而且效率非常低:

示例向量:exp = c(1,1,1,0,0,1,2,0,2,0,1,0,2)
想要的结果:1,1,1,1,1,1,2,0,0,0,1,1,2
谢谢

最佳答案

您可以使用 rle & shift来自 数据表 - 以下列方式打包:

library(data.table)

# create the run-length object
rl <- rle(x)

# create indexes of the spots in the run-length object that need to be replaced
idx1 <- rl$values == 0 & shift(rl$values, fill = 0) == 1 & shift(rl$values, fill = 0, type = 'lead') %in% 1:2
idx0 <- rl$values == 2 & shift(rl$values, fill = 0) == 0 & shift(rl$values, fill = 2, type = 'lead') %in% 0:1

# replace these values
rl$values[idx1] <- 1
rl$values[idx0] <- 0

现在您将通过使用 inverse.rle 获得所需的结果:
> inverse.rle(rl)
[1] 1 1 1 1 1 1 2 0 0 0 1 1 2

作为 shift 的替代品-function,你也可以使用 laglead来自 的函数dplyr .

如果您想评估两种方法的速度, microbenchmark -package 是一个有用的工具。您会在下面找到 3 个基准测试,每个基准测试针对不同的向量大小:
# create functions for both approaches
jaap <- function(x) {
rl <- rle(x)

idx1 <- rl$values == 0 & shift(rl$values, fill = 0) == 1 & shift(rl$values, fill = 0, type = 'lead') %in% 1:2
idx0 <- rl$values == 2 & shift(rl$values, fill = 0) == 0 & shift(rl$values, fill = 2, type = 'lead') %in% 0:1

rl$values[idx1] <- 1
rl$values[idx0] <- 0

inverse.rle(rl)
}

john <- function(x) {
Reduce(f, x, 0, accumulate = TRUE)[-1]
}

执行基准:
# benchmark on the original data

> microbenchmark(jaap(x), john(x), times = 100)
Unit: microseconds
expr min lq mean median uq max neval cld
jaap(x) 58.766 61.2355 67.99861 63.8755 72.147 143.841 100 b
john(x) 13.684 14.3175 18.71585 15.7580 23.902 50.705 100 a

# benchmark on a somewhat larger vector

> x2 <- rep(x, 10)
> microbenchmark(jaap(x2), john(x2), times = 100)
Unit: microseconds
expr min lq mean median uq max neval cld
jaap(x2) 69.778 72.802 84.46945 76.9675 87.3015 184.666 100 a
john(x2) 116.858 121.058 127.64275 126.1615 130.4515 223.303 100 b

# benchmark on a very larger vector

> x3 <- rep(x, 1e6)
> microbenchmark(jaap(x3), john(x3), times = 20)
Unit: seconds
expr min lq mean median uq max neval cld
jaap(x3) 1.30326 1.337878 1.389187 1.391279 1.425186 1.556887 20 a
john(x3) 10.51349 10.616632 10.689535 10.670808 10.761191 10.918953 20 b

由此可以得出结论, rle -approach 在应用于大于 100 个元素的向量时具有优势(这可能几乎总是如此)。

关于r - 填充两个指定值之间的所有条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44205656/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com