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、用pmax
做elementwise
max转换成data.frame
后,return输出unlist
list
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
可重现的例子:
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、用pmax
做elementwise
max转换成data.frame
后,return输出unlist
list
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