在连续的行中查找值

时间:2019-01-14 13:55:07

标签: r for-loop if-statement

下面是我拥有的数据框的示例。

ID     X      
1      1     
2      2      
3      1      
4      0      
5      0      
6      1      
7      4
8      5 
9      6
10     7
11     0 
12     0

我想对其应用逻辑,以查看是否有3个或更多连续行的值大于0。如果他们这样做,我想在另一列中对其进行标记。因此,输出将如下所示。

ID     X      Y
1      1      1
2      2      1
3      1      1
4      0      0
5      0      0
6      1      1
7      4      1
8      5      1
9      6      1
10     7      1
11     0      0
12     0      0

扩展- 如何为每个组赋予不同的Y值,以获得以下输出?

ID     X      Y
1      1      1
2      2      1
3      1      1
4      0      0
5      0      0
6      1      2
7      4      2
8      5      2
9      6      2
10     7      2
11     0      0
12     0      0

2 个答案:

答案 0 :(得分:4)

带有base R的一个选项。使用rle在'X'中查找大于0的相邻值,然后基于rep

进行lengths求和
df1$Y <- with(rle(df1$X > 0), as.integer(rep(values & lengths > 2, lengths)))
df1$Y
#[1] 1 1 1 0 0 1 1 1 1 1 0 0

OP帖子中的最新案例

df1$Y <- inverse.rle(within.list(rle(df1$X > 0), {
             i1 <- values & (lengths > 2)
      values[i1] <- seq_along(values[i1])}))
df1$Y
#[1] 1 1 1 0 0 2 2 2 2 2 0 0

或使用rleid中的data.table

library(data.table)
setDT(df1)[, Y := as.integer((.N > 2) * (X > 0)),rleid(X > 0)]

数据

df1 <- structure(list(ID = 1:12, X = c(1L, 2L, 1L, 0L, 0L, 1L, 4L, 5L, 
 6L, 7L, 0L, 0L)), class = "data.frame", row.names = c(NA, -12L
 ))

答案 1 :(得分:2)

我们可以使用rleid中的data.table创建组,并在ave中使用它,获取每个组的length并将1分配给长度大于等于的组到3。

library(data.table)
df$Y <- as.integer(ave(df$X, rleid(df$X > 0), FUN = length) >= 3)

df
#   ID X Y
#1   1 1 1
#2   2 2 1
#3   3 1 1
#4   4 0 0
#5   5 0 0
#6   6 1 1
#7   7 4 1
#8   8 5 1
#9   9 6 1
#10 10 7 1
#11 11 0 0
#12 12 0 0

编辑

对于更新后的帖子,我们可以通过进行以下操作将data.table的上述dplyr部分包括在内

library(dplyr)
library(data.table)

df %>%
  group_by(group = rleid(X > 0)) %>%
  mutate(Y = ifelse(n() >= 3 & row_number() == 1, 1, 0)) %>%
  ungroup() %>%
  mutate(Y = cumsum(Y) * Y) %>%
  group_by(group) %>%
  mutate(Y = first(Y)) %>%
  ungroup() %>%
  select(-group)


#     ID     X     Y
#   <int> <int> <dbl>
# 1     1     1     1
# 2     2     2     1
# 3     3     1     1
# 4     4     0     0
# 5     5     0     0
# 6     6     1     2
# 7     7     4     2
# 8     8     5     2
# 9     9     6     2
#10    10     7     2
#11    11     0     0
#12    12     0     0