Return 从 R 中的向量中有条件地选择的最大对

Return maximum of conditionally selected pairs from a vector in R

可重现的例子:

set.seed(1)
A <- round(runif(12, min = 1, max = 5))

> A
 [1] 1 2 2 4 3 4 3 4 5 3 4 5

expectedResult <- c(max(A[1], A[4]), max(A[2], A[5]), max(A[3], A[6]), max(A[7], A[10]), max(A[8], A[11]), max(A[9], A[12]))

> expectedResult
[1] 4 3 4 3 4 5

每个A都需要看成是6个元素的段集合。比如这里的A有A[1:6]和A[7:12]2个段。对于每个段,将前 3 个元素与接下来的 3 个元素进行比较。因此我需要服用 max(A[1],A[4])max(A[2], A[5])max(A[2], A[5])max(A[3], A[6])max(A[7], A[10])max(A[8], A[11])max(A[9], A[12]).

我的原始向量比这个例子有更多的元素,因此我需要一个更简单的方法来做到这一点。此外,速度也是原始计算的一个因素,因此也在寻找快速解决方案。

我们可以通过 'n' 个元素创建一个 split 向量的函数,循环遍历 list,创建一个 matrix 并指定 nrow 2、用pmaxelementwise max转换成data.frame后,return输出unlistlist

f1 <- function(vec, n) {
       lst1 <- split(vec, as.integer(gl(length(vec), n, length(vec))))
       unname(unlist(lapply(lst1, function(x) 
       do.call(pmax, as.data.frame(t(matrix(x, nrow = 2, byrow = TRUE)))))))
}

-输出

> f1(A, 6)
[1] 4 3 4 3 4 5

如果长度不是3或6的倍数,另一种选择是拆分后用tapply做一个group by操作

unname(unlist(lapply(split(A, as.integer(gl(length(A), 6, 
    length(A)))), function(x) tapply(x, (seq_along(x)-1) %% 3 + 1, FUN = max))))
[1] 4 3 4 3 4 5

数据

A <- c(1, 2, 2, 4, 3, 4, 3, 4, 5, 3, 4, 5)

基础 R 中的另一个选项:

a <- 6
unlist(tapply(A, gl(length(A)/a, a),
  function(x) pmax(head(x, a/2), tail(x, a/2))),, FALSE)
[1] 4 3 4 3 4 5

甚至

a <- 6
unlist(tapply(A, gl(length(A)/a, a),
  function(x) do.call(pmax, data.frame(matrix(x, ncol = 2)))),, FALSE)
[1] 4 3 4 3 4 5

您可以将向量重新整形为 3 维数组,按列拆分,并取平行最大值。就基础 R 而言,这应该是非常有效的。

do.call(pmax.int, asplit(`dim<-`(A, c(3,2,2)), 2))

[1] 4 3 4 3 4 5