【问题标题】:how to loop a vector comparing rows without FOR如何在没有 FOR 的情况下循环比较行的向量
【发布时间】:2015-08-11 12:04:22
【问题描述】:

由于优化问题,我需要一些提示才能在向量中进行有效循环,但对于“FOR…”循环。 乍一看,推荐使用apply()sapply()等函数。

我有一个向量转换成矩阵:

x1<-c(1,2,4,1,4,3,5,3,1,0)

循环遍历向量,如果 x[i]>x[i+1],我需要替换所有 x1[i+1]=x1[i]。 例子: 输入向量:

x1<-as.matrix(c(1,2,4,1,4,3,5,3,1,0))

输出向量:

c(1,2,4,4,4,4,5,5,5,5)

我的方法是在apply() 中使用用户函数,但我在如何正确编码用户函数中 x[i] 和 x[i+1] 的关系时遇到了一些困难。 我将非常感谢您的想法或提示。

【问题讨论】:

  • @Khashaa 请考虑将其作为解决方案发布。这是一个很好的选择。
  • @akrun 对于正确答案来说太短了。您不妨将其添加到您的答案中。
  • @Khashaa 我不会偷你的优秀答案:-)。另外,如果答案简洁而简短,那不是你的错
  • 如果您不介意,我会将其添加到一般性答案中。

标签: r matrix vector


【解决方案1】:

一般而言,您可以使用Reduceaccumulate=TRUE 进行累积运算

Reduce(max,x1,accumulate=TRUE)
# [1] 1 2 4 4 4 4 5 5 5 5

但正如@Khashaa 指出的那样,常见情况cumsumcumprodcummin 和您的cummax 是作为高效的基本函数提供的。

cummax(x1)
# [1] 1 2 4 4 4 4 5 5 5 5

【讨论】:

  • 谢谢 A. 韦伯。 cummax(x1) 真的很棒。所有选项的最佳结果 - 在 1mio 项的向量上经过的时间是 0,02 秒 :-)
【解决方案2】:

我们可以使用ave 做到这一点。 (使用vector x1)

 ave(x1,cumsum(c(TRUE,x1[-1]>x1[-length(x1)])), FUN=function(x) head(x,1))
 #[1] 1 2 4 4 4 4 5 5 5 5

我们根据 OP 帖子中描述的条件创建一个分组变量。检查后续元素(x1[-1] - 删除的第一个元素)是否大于当前元素(x1[-length(x1)] - 删除的最后一个元素)。

 x1[-1]>x1[-length(x1)]
 #[1]  TRUE  TRUE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE

长度比向量 x1 的长度小一。因此,我们追加TRUE 以使长度相等,然后执行cumsum

 cumsum(c(TRUE,x1[-1]>x1[-length(x1)]))
 #[1] 1 2 3 3 4 4 5 5 5 5

我们将其用作ave 中的分组变量并选择“x1”的第一个观察值 每个组内


另一种选择是像以前一样获取逻辑索引 (c(TRUE, x1[-1] &gt; x1[-length(x1)])),取反它 (!) 使 TRUE 变为 FALSE,将 FALSE 变为 TRUE,将 TRUE 值转换为 'NA' (NA^(!...)) ,然后使用 library(zoo) 中的 na.locfNA 值替换为前面的非 NA 值。

 library(zoo)
 na.locf(x1*NA^(!c(TRUE,x1[-1]>x1[-length(x1)])))
 #[1] 1 2 4 4 4 4 5 5 5 5

【讨论】:

  • 你的提示真的很棒!
  • @DimonD。很高兴知道它有帮助。感谢您的反馈。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-12
  • 1970-01-01
  • 2019-07-13
  • 2014-03-13
  • 2020-02-29
  • 1970-01-01
相关资源
最近更新 更多