【问题标题】:alternative to a for loop for replacing a subset of elements in a matrix with elements in a vector in R替代 for 循环,用于用 R 中的向量中的元素替换矩阵中的元素子集
【发布时间】:2013-06-30 09:33:35
【问题描述】:

我正在使用 for 循环使用 mycons 向量替换 myarray 的元素子集。每列中的子集将从mydates直到结束。 for 循环是否有替代方案?

mydates <- as.Date(c('2013-06-05','2013-06-16','2013-06-22'))
mycons <- c(0.5,1/7,0.25)
dates <- seq(as.Date('2013-06-01'),Sys.Date(),"days")
myarray <- matrix(rep(1,length(dates)*length(mydates)),length(dates),length(mydates))

for (i in 1:length(mycons)) {
  myarray[which(dates>mydates[i]),i] <- mycons[i]
}

【问题讨论】:

  • 这真的是你的数据吗?还是这是简化版?因为正如所写的那样,这既快又可能根本不需要for 循环,因为您似乎只是在以一种相当简单的方式重新编码您的数据。
  • 那么,您需要有关该错误的帮助吗?如果是这样,请更新您的问题。或者,您想谈谈生成myarray 矩阵的方法吗?
  • @Thomas 对不起,我虽然理解你的意思,但现在如果删除for 循环,我无法让代码工作。如果您能帮助我以不同的方式生成myarray,我将不胜感激。
  • 通过描述您想要的myarray 应该是什么样子来更新您的问题。然后人们可以帮助您获得预期的结果,而不是解决您在使用此特定代码时可能遇到的任何问题,从表面上看,这并不是获得任何结果的好方法。
  • @Thomas 如果代码是高效的,我就不必在这里问了,但它做了它应该做的事情。无论如何感谢您最初的支持。

标签: r apply tapply


【解决方案1】:

您要比较的项目属于不同的类别:字符和日期。 (我得到一个用 1 填充的整个矩阵。)

试试这个:

 mydates <- as.Date(mydates) # then the comparisons will more sensible

它得到了一个矢量化的答案,我使用了outer 并稍微重新安排了逻辑以创建一个具有“新”值的矩阵,然后将失败的项目设置回分层值 1:

myarray2 <-matrix(mycons, 
                nrow=length(dates), ncol=length(mydates), byrow=TRUE)
myarray2[  outer(dates, mydates, "<=") ] <- 1
myarray2

我尝试使用 mapply,以为我可以做一些事情,比如从两个序列中传递“并行项目”,但我无法让“i”索引占据主导地位。

mapply(function(x,y) {myarray[i , ] <- y[x>dates]} , mydates, mycons)

for 循环的典型改造:您几乎总是可以将 for 循环重构为 sapply 操作:

 sapply( 1:length(mycons), function(idx){ 
          myarray[which(dates>mydates[idx]),idx] <- mycons[idx]; myarray[,idx]})

我怀疑有人可以构造一个sweep 操作来执行此操作,但我还没有真正了解sweep

如果您想采用 @Ferdinand.Kraft 建议的构建与 myarray 长度相同的向量的路径,但要保持在 obj[cond] &lt;- value 的范式内,请执行以下操作:

 myarray[  outer(dates, mydates, ">") ] <- 
        rep(mycons, each=length(dates) )[ outer(dates, mydates, ">")]

这是通过将相同的条件应用于&lt;- 操作的两侧来使用条件赋值的示例。它可以非常快。

【讨论】:

  • 感谢我更新了代码。您知道for 循环的替代方法吗?
  • 我可以想到对mapply 的等效调用,但我不明白您为什么需要这样做。 for-loops 对于这种操作同样快。
  • 感谢您的帮助。我正在学习并且经常读到由于内存问题,建议使用矢量化而不是循环。尽管在这种情况下循环会更合适,但如果不太复杂,您介意使用mapply 版本吗?它会让我了解它是如何工作的。
  • 如果你做一个更小的例子,我不介意提供帮助。当我检查最后一个时,它产生了巨大的输出。您还应该考虑阅读mapply 帮助页面并在该页面底部运行示例。
  • 我已经减小了myarray 的维度。关于帮助页面,我看过但还是不太明白,只是知道如何使用单变量的。
【解决方案2】:

你可以用这个:

myarray <- ifelse(outer(dates, mydates, `>`), rep(mycons, each=length(dates)), 1)

【讨论】:

    猜你喜欢
    • 2017-02-27
    • 2020-08-12
    • 2017-05-09
    • 1970-01-01
    • 2014-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多