如果我正确理解了这个问题,你想检测什么时候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 ,因为第一个元素总是在 class 中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
或者,因为to 是一个因素是有意义的:
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,并且避免生成大量中间向量和列表等。而且它可以写在一行上也很整洁 :))