基于比较两个其他向量的元素“滞后”的新向量?

时间:2009-09-08 17:24:42

标签: r

我有两个向量,subjecttarget。我想基于两个现有向量之间的比较创建一个新向量,并将元素进行比较lagged。我已经使用下面的循环解决了这个问题,但我基本上想知道使用apply是否有更优雅的解决方案?

subject <- c(200, 195, 190, 185, 185, 185, 188, 189, 195, 200, 210, 210)
target <- c(subject[1], subject[1]-cumsum(rep(perweek, length(subject)-1)))
adjtarget <- target                                               

for (i in 1:(length(subject)-1)) {
  if (subject[i] > adjtarget[i]) {                
    adjtarget[i+1] <- adjtarget[i]           
   } else {                                       
    adjtarget[i+1] <- adjtarget[i]-perweek  }
   }
 }

2 个答案:

答案 0 :(得分:1)

这并不能完全解决您的问题,但可能会指出一个有用的方向。我忽略了更改adjtarget和比较它之间的相互作用,并显示了类似的问题,我们将其与常量target进行比较。然后可以将循环中的if更改为矢量比较:

lv <- but.last(subject) > but.last(target)
ind <- which(lv)

准备结果向量(我称之为x,因为它与adjtarget}的结果不同target的移位副本并指定更改它:

x <- c(target[1], but.last(target))  # corresponds to the true branch of the `if`
x[ind+1] <- target[ind] - perweek    # corresponds to the false branch

可替换地,

x <- c(target[1], but.last(target) - (!lv)*perweek

正如我所说,这并不能解决你的问题,但也许我们可以从这里开始。

答案 1 :(得分:1)

只是为了澄清,如果我理解你的代码,这就是你正在寻找的那种结果......

> (goal <- cbind(subject,target,adjtarget))

      subject target adjtarget
 [1,]     200    200       200
 [2,]     195    198       198
 [3,]     190    196       196
 [4,]     185    194       194
 [5,]     185    192       192
 [6,]     185    190       190
 [7,]     188    188       188
 [8,]     189    186       186
 [9,]     195    184       186
[10,]     200    182       186
[11,]     210    180       186
[12,]     210    178       186

如果我是对的,那么向量化的挑战就是在adjtarget中重复分配186。矢量化代码将在将其分配到左侧(LHS)之前评估右侧(RHS)。因此,向量化代码将不会在第9行的adjtarget中看到更新的值,直到赋值完成为止。

> y <- ifelse(subject > target, 1, 0) # matches TRUE case
> x <- target
> x[ind+1] <- target[ind]
> cbind(goal, x, y)
      subject target adjtarget   x y
 [1,]     200    200       200 200 0
 [2,]     195    198       198 198 0
 [3,]     190    196       196 196 0
 [4,]     185    194       194 194 0
 [5,]     185    192       192 192 0
 [6,]     185    190       190 190 0
 [7,]     188    188       188 188 0
 [8,]     189    186       186 186 1
 [9,]     195    184       186 186 1 # assigned correctly (?)
[10,]     200    182       186 184 1 # incorrect x; should be 186
[11,]     210    180       186 182 1 # incorrect x; should be 186
[12,]     210    178       186 180 1 # incorrect x; should be 186