R - 如果先前的x行与每个前进行相比具有相等或更小的值,则识别行

时间:2013-07-08 08:17:44

标签: r

this question之后,我现在必须检查之前的x行是否具有递减(或保持不变)的值。

我无法获得我期望的行为,即m1-> m2,m2-> m3,m3-> m4的差异在m4中返回TRUE / FALSE。我认为我的方向是正确的,并且我认为filter的滞后可能是问题,但是在摆弄内部\ _外{{}之后我无法按预期工作amendedcheckfun 1}} s,rev&的顺序diffNA声明。

民间可以建议repamendedcheckfun相同但行方向相反吗?

checkfun



在check2中修改了checkck输出

library("plyr")
df<-data.frame(ID=1,Month=1:15,Bal=seq(from=500, to=220, by=-20))
df$Bal[6] <- 505
df$Bal[11] <- 505

origcheckfun <- function(x,n) {
  rev(filter(rev(c(diff(x) <= 0,NA)),rep(1,pmin(n,length(x)),sides=1))) == n  }

amendedcheckfun <- function(x,n) {
  rev(filter(c(diff(x) <= 0,NA),rep(1,pmin(n,length(x)),sides=1))) == n }

ddply(df,.(ID),transform,diff=c(diff(Bal) ,NA),check=checkfun(Bal,3), 
  check2=amendedcheckfun(Bal,3))

理想输出

   ID Month Bal diff check check2
1   1     1 500  -20    NA     NA
2   1     2 480  -20  TRUE     NA
3   1     3 460  -20  TRUE   TRUE  # check2 correct
4   1     4 440  -20 FALSE   TRUE
5   1     5 420   85 FALSE  FALSE  # check2 not correct - id=2:4 all decreases
6   1     6 505 -125 FALSE  FALSE
7   1     7 380  -20  TRUE  FALSE
8   1     8 360  -20  TRUE   TRUE  # check2 not correct - id=5 is increase
9   1     9 340  -20 FALSE   TRUE  # check2 correct
10  1    10 320  185 FALSE  FALSE  # check2 not correct - id=7:9 all decreases
11  1    11 505 -225 FALSE  FALSE
12  1    12 280  -20  TRUE  FALSE
13  1    13 260  -20  TRUE   TRUE
14  1    14 240  -20    NA   TRUE
15  1    15 220   NA    NA     NA  # check2 not correct - should show TRUE

2 个答案:

答案 0 :(得分:1)

这是一个应该做你想要的功能

amendedcheckfun <- function(x, n){
    c(rep(NA, n-1), sapply(n:length(x), function(i, x, n) {all(diff(x[(i-n+1):i]) <= 0)}, x=x, n=n))
}

ddply(df, .(ID), transform, diff = c(diff(Bal), NA), check2 = amendedcheckfun(Bal, 4))

请注意,amendedcheckfun的第二个参数是4,对应于要检查的连续值的数量。

您的示例的输出是

ID Month Bal diff check2
1   1     1 500  -20     NA
2   1     2 480  -20     NA
3   1     3 460  -20     NA
4   1     4 440  -20   TRUE
5   1     5 420   85   TRUE
6   1     6 505 -125  FALSE
7   1     7 380  -20  FALSE
8   1     8 360  -20  FALSE
9   1     9 340  -20   TRUE
10  1    10 320  185   TRUE
11  1    11 505 -225  FALSE
12  1    12 280  -20  FALSE
13  1    13 260  -20  FALSE
14  1    14 240  -20   TRUE
15  1    15 220   NA   TRUE

答案 1 :(得分:0)

由于每个ID的观察数量不同而且没有超过70k以上的记录,所以我很难实现,直到我从包裹动物园看到了rollapply功能。

它仍然没有惊人的速度,但是:

newcheckfun<- function(x,n) {rollapply(x,n,min,fill = NA,partial=1,align="right")}

df<-ddply(df,.(ID),transform
          ,diffs=c(0,diff(Bal)<=0)
          ,movcheck=newcheckfun(c(0,diff(Bal)<=0),3))