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

时间:2013-07-03 16:16:28

标签: r

我正在尝试确定下一个x(6是当前的计划,但这可能会有所变化),每个月的余额保持不变或减少。

我在Excel中执行此操作,以便从当前月份的值开始,并将下个月的值与之比较,以确定它是保持不变还是减少等等。

=IF(AND(H3<=H2,H4<=H3,H5<=H4,H6<=H5,H7<=H6,H8<=H7),1,0)

这不是最灵活或最优雅的公式,因为它是初步探索的一部分。为了使一切更清晰,更可重复,我想把我的计算结果放到R中。

这是一个基本数据集,就像我多个月内多个ID的数据一样。

rbind(data.frame(ID=1,Month=1:11,Bal=seq(from=500, to=300, by=-20)),
  data.frame(ID=2,Month=1:10,Bal=rep(200,10)),
  data.frame(ID=3,Month=1:11,Bal=seq(from=300, to=500, by=20)))

根据行级别的原始数据计算某些内容或在ddply内部工作的内容是理想的解决方案变体。

我还是R的新手,我确信这是一个优雅的解决方案,但我真的看不到它。任何人都有一个简洁的解决方案,或者可以指出我应该研究的各种关键项的方向,以尝试找到解决方案?

2 个答案:

答案 0 :(得分:3)

我不确定我是否理解正确:

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

此函数计算连续值之间的差异,并检查它们是否为<= 0.过滤器对满足条件的后续n个差异的数量求和。最后将该数字与n进行比较,以查看它们是否满足条件。 (仅使用rev,因此可以使用单侧过滤器。)

DF$Bal[6] <- 505 #to not only have equal differences
library(plyr)
#example with 3 next values
ddply(DF,.(ID),transform,check=checkfun(Bal,3))
#    ID Month Bal check
# 1   1     1 500  TRUE
# 2   1     2 480  TRUE
# 3   1     3 460 FALSE
# 4   1     4 440 FALSE
# 5   1     5 420 FALSE
# 6   1     6 505  TRUE
# 7   1     7 380  TRUE
# 8   1     8 360  TRUE
# 9   1     9 340    NA
# 10  1    10 320    NA
# 11  1    11 300    NA
# 12  2     1 200  TRUE
# 13  2     2 200  TRUE
# 14  2     3 200  TRUE
# 15  2     4 200  TRUE
# 16  2     5 200  TRUE
# 17  2     6 200  TRUE
# 18  2     7 200  TRUE
# 19  2     8 200    NA
# 20  2     9 200    NA
# 21  2    10 200    NA
# 22  3     1 300 FALSE
# 23  3     2 320 FALSE
# 24  3     3 340 FALSE
# 25  3     4 360 FALSE
# 26  3     5 380 FALSE
# 27  3     6 400 FALSE
# 28  3     7 420 FALSE
# 29  3     8 440 FALSE
# 30  3     9 460    NA
# 31  3    10 480    NA
# 32  3    11 500    NA

答案 1 :(得分:2)

如果df是您的data.frame:

你可以使用以下方法找到连续的差异:

df$diff <- do.call("c",lapply(unique(df$ID), function(x) c(0,diff(df$Bal[df$ID==x]))))

这假设您希望将这些计算分开用于不同的ID。

> head(df)
  ID Month Bal diff
1  1     1 500    0
2  1     2 480  -20
3  1     3 460  -20
4  1     4 440  -20
5  1     5 420  -20
6  1     6 400  -20

现在,对于给予k=6(比如说​​),请检查:

sapply(unique(df$ID), function(x) ifelse(sum(df$diff[df$ID==x][1:k] < 0)!=0,1,0)) 
[1] 1 0 0

每个ID返回值1(所有差异均为负数)或0(所有差异均为正数)。