检查向量中的数字是否在R中交替

33qvvth1  于 2023-07-31  发布在  其他
关注(0)|答案(3)|浏览(102)

我需要检查向量的第一个数字是否小于第二个数字,第二个数字是否大于第三个数字,等等。到目前为止,我可以这样计算向量的数的差:

n <- sample(3) #may n = 132
diff(n) # outputs 2 -1

字符串
我需要检查第一个数字是否为正数,第二个数字是否为负数等。我遇到的问题是,我需要程序对长度为n的向量做这件事。我该如何实现这一点?
由于我不太清楚我在这里试图做什么,我将给予一个更好的例子:
v可以是向量c(1,2,4,3)。
我需要检查向量的第一个数字是否小于第二个,第二个是否大于第三个,第三个是否小于第四个。
所以我需要检查1 < 2 >4 < 3。(这个向量不符合要求)我得到的每个数字都将> 0,并且保证只出现一次。
这个过程需要推广到给定的n,n> 0,是一个自然数。

djmepvbi

djmepvbi1#

v <- c(1, 2, 4, 3)
all(sign(diff(v)) == c(1, -1))
# [1] FALSE
# Warning message:
# In sign(diff(v)) == c(1, -1) :
# longer object length is not a multiple of shorter object length

字符串
我们可以安全地忽略警告消息,因为我们故意使用了“回收”(这意味着c(1, -1)被隐式重复以匹配sign(diff(v))的长度)。

  • 编辑:* 考虑到@digEmAll的评论,如果你想在序列开始时允许负差异而不是正差异,那么这个天真的变化应该做到这一点:
diffs <- sign(diff(v))
all(diffs == c(1, -1)) || all(diffs == c(-1, 1))

pb3s4cty

pb3s4cty2#

如果我们需要找出是否有替代正、负的区别,那么

all(rle(as.vector(tapply(n, as.integer(gl(length(n),
         2, length(n))), FUN = diff)))$lengths==1)
#[1] TRUE

字符串
此外,正如@digEmAll评论和我最初的React的变化

all(rle(sign(diff(n)) > 0)$lengths == 1)

数据

n <- c(1, 2, 4, 3)

flvlnr44

flvlnr443#

我用来检查交替符号的函数是:

isAlt <- function(x) all(abs(diff(sign(x))) == 2)

字符串
这是因为如果符号交替,那么你看到的要么是-1对1,要么是相反,两者的差值总是绝对量值2。如果两个条目具有相同的符号,则它们的符号之差为0。在您的示例中,您首先在向量上运行diff,以转换“更大”与“更大”。更小的“到”>0对“< 0”。
下面是它如何工作的一个例子。

isAlt <- function(x) all(abs(diff(sign(x))) == 2)

test1 <- 1:10
test2 <- c(1, 2, 1, 3, 1, 4, 1, 5, 1, 6)
# Wrap test2 around to check large --> small
test3 <- c(test2[-1], 1)

> isAlt(diff(test1))
[1] FALSE
> isAlt(diff(test2))
[1] TRUE
> isAlt(diff(test3))
[1] TRUE


对于时间,我将与@akrun的版本进行比较。他的优点是将diff构建到函数中,因此可以在任何向量上调用它。然而,我的版本的好处是使用 * 只 * 向量化函数,因此不需要任何*apply调用,这就是为什么它快了大约7- 10倍。当然,它是以微秒为单位的,但是如果你在另一个过程中调用10,000多次,那么可能会增加。

isAlt.akrun <- function(x) {
  all(rle(as.vector(tapply(x, as.integer(gl(length(x), 2, length(x))),
                           FUN = diff)))$lengths==1)
}

library(microbenchmark)

bmT1 <- microbenchmark(isAlt(diff(test1)), isAlt.akrun(test1),
                       check = 'identical', control = list(order = 'block'),
                       times = 1000L)

bmT2 <- microbenchmark(isAlt(diff(test2)), isAlt.akrun(test2),
                       check = 'identical', control = list(order = 'block'),
                       times = 1000L)

bmT3 <- microbenchmark(isAlt(diff(test3)), isAlt.akrun(test3),
                       check = 'identical', control = list(order = 'block'),
                       times = 1000L)

print(bmT1, order = 'median')
Unit: microseconds
               expr  min   lq     mean median   uq    max neval cld
 isAlt(diff(test1)) 11.6 12.0  13.0575   12.2 12.6   69.5  1000  a 
 isAlt.akrun(test1) 88.6 93.1 104.4684   95.1 98.4 3239.8  1000   b

print(bmT2, order = 'median')
Unit: microseconds
               expr  min   lq     mean median    uq    max neval cld
 isAlt(diff(test2)) 11.3 11.8  12.4792   11.9  12.2  178.7  1000  a 
 isAlt.akrun(test2) 89.8 93.7 101.3557   97.1 100.0 2447.4  1000   b

Unit: microseconds
               expr  min   lq    mean median uq    max neval cld
 isAlt(diff(test3)) 11.2 11.6 12.0837   11.8 12   52.2  1000  a 
 isAlt.akrun(test3) 85.8 91.8 98.6858   94.2 97 2391.8  1000   b

相关问题