如果我对问题的理解正确,那么您想检测何时h_no
不增加,然后增加class
。(我将逐步解决这个问题,最后有一个自包含的功能。)
加工
我们目前只关心该h_no
列,因此我们可以从数据框中提取该列:
> h_no <- data$h_no
我们想检测何时h_no
不上升,这可以通过计算连续元素之间的差为负或零来实现。R提供diff
给我们差向量的函数:
> d.h_no <- diff(h_no)
> d.h_no
[1] 1 1 1 -3 1 1 1 1 1 1 -6 1 1 1
一旦有了这些,找到一个非正数的问题就很简单了:
> nonpos <- d.h_no <= 0
> nonpos
[1] FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE
[13] FALSE FALSE
在R中,TRUE
和FALSE
基本上与1
和相同0
,因此,如果我们得到的累加和nonpos
,它将在(几乎)适当的位置增加1。的cumsum
功能(这是基本上相反diff
)可以做到这一点。
> cumsum(nonpos)
[1] 0 0 0 1 1 1 1 1 1 1 2 2 2 2
但是,有两个问题:数字太小;并且,我们缺少第一个元素(第一堂课应该有四个)。
第一个问题很简单地解决了:1+cumsum(nonpos)
。第二个只需要1
在向量的前面添加a ,因为第一个元素始终在类中1
:
> classes <- c(1, 1 + cumsum(nonpos))
> classes
[1] 1 1 1 1 2 2 2 2 2 2 2 3 3 3 3
现在,我们可以将其附加到我们的数据框架上cbind
(通过使用class=
语法,我们可以为列指定class
标题):
> data_w_classes <- cbind(data, class=classes)
而data_w_classes
现在包含的结果。
最后结果
我们可以将这些行压缩在一起,并将它们全部包装成一个函数,以使其更易于使用:
classify <- function(data) {
cbind(data, class=c(1, 1 + cumsum(diff(data$h_no) <= 0)))
}
或者,由于class
成为一个因素是有意义的:
classify <- function(data) {
cbind(data, class=factor(c(1, 1 + cumsum(diff(data$h_no) <= 0))))
}
您可以使用以下任一函数:
> classified <- classify(data) # doesn't overwrite data
> data <- classify(data) # data now has the "class" column
(解决该问题的方法是好的,因为它避免了显式迭代(通常建议R使用该方法,并且避免生成大量中间向量和列表等。而且它还可以整齐地写在一行上:)