R语言 创建某个值的连续运行计数器,并根据条件忽略行

gopyfrb3  于 2023-02-01  发布在  其他
关注(0)|答案(1)|浏览(134)

我有一个数据集,看起来像这样:

# A tibble: 987 × 2
   time   counts
   <time> <chr> 
 1 07:33  1358  
 2 07:34  1072  
 3 07:35  112   
 4 07:36  316   
 5 07:37  0     
 6 07:38  16    
 7 07:39  32    
 8 07:40  0     
 9 07:41  0     
10 07:42  92    
# … with 977 more rows

我需要创建一个新变量,为连续运行分配一个唯一的值,并在计数== 0时重新启动。此外,如果计数器以0开头,而接下来两个连续行的值〈100,我希望计数器忽略这两行,并将其视为0。对于计数〉1000的一行也是如此。因此,如果计数== 0的行的下一行大于1000,我想将其视为0。
下面是计数器的条件:

  • 从0重新开始
  • 如果紧接在计数== 0的行之后,有两个连续行的计数〈100或一行的计数〉1000,则忽略行(将其视为0)。

我必须这样做,因为我需要删除那些有60个或更多计数== 0的连续行的行,但是这些行可以包括两个计数〈100的连续行或一个计数〉1000的连续行。
我不确定这是否有意义。希望,有意义!
我尝试了以下方法:

db %>% 
  mutate(consec_id = rleid(counts==0))

但是我不知道如何告诉R基于特定条件忽略某些行。
我也尝试过使用循环,但我对循环非常陌生,所以我没有得到我想要的:

# Loop through the dataset and update the "wear_status" variable
for (i in 2:nrow(day1)) {
  # Check if current counts = 0
  if (db$counts[i] == 0) {
    consec_counts <- 0
    db$wear_status[i] <- 0
  } else {
    # Check if current counts are between 1 and 100
    if (db$counts[i] > 1 || db$counts[i] < 100) {
      consec_counts <- consec_counts + 1
    } else {
      consec_counts <- 0
    }
    # Check if current counts > 100 or 3 consecutive rows of counts = 1 or 100
    if (db$counts[i] > 100 || consec_counts <= 2) {
      consec_counts <- 0
      db$wear_status[i] <- 1
    }
  }
}

这是我的预期输出:

# A tibble: 987 × 2
   time   counts  counter
   <time> <chr> 
 1 07:33  1358     1
 2 07:34  1072     1
 3 07:35  112      1  
 4 07:36  316      1
 5 07:37  0        2
 6 07:38  16       2  
 7 07:39  32       2  
 8 07:40  0        2
 9 07:41  0        2
10 07:42  92       3
11 07:43  80       3
12 07:44  78       3
13 07:45  0        4
# … with 977 more rows

谢谢大家!

91zkwejq

91zkwejq1#

这是不使用循环的尝试。
有3个条件会导致counts值变为零:
1.如果前一个值为0,则当前值〈100,后一个值〈100,后一个值(当前值后2个值)为0。
1.如果前一个值的前一个值为0,则前一个值〈100,当前值〈100,后一个值为0。
1.如果前一个值为0,则当前值大于1000,后一个值为0。
您可以使用laglead查看之前和之后的值。如果您使用数字,例如lag(counts, n = 2),则会考虑2个值之外的值(n是laglead的位置数)。

library(tidyverse)
library(data.table)

df %>%
  mutate(new_counts = ifelse(
    (lag(counts) == 0 & counts < 100 & lead(counts) < 100 & lead(counts, 2) == 0) |
    (lag(counts, 2) == 0 & lag(counts) < 100 & counts < 100 & lead(counts) == 0) |
    (lag(counts) == 0 & counts > 1000 & lead(counts) == 0),
    0,
    counts
  )) %>%
  mutate(counter = rleid(new_counts == 0))

产出

time counts new_counts counter
1  07:33   1358       1358       1
2  07:34   1072       1072       1
3  07:35    112        112       1
4  07:36    316        316       1
5  07:37      0          0       2
6  07:38     16          0       2
7  07:39     32          0       2
8  07:40      0          0       2
9  07:41      0          0       2
10 07:42     92         92       3
11 07:43     80         80       3
12 07:44     78         78       3
13 07:45      0          0       4

数据

df <- structure(list(time = c("07:33", "07:34", "07:35", "07:36", "07:37", 
"07:38", "07:39", "07:40", "07:41", "07:42", "07:43", "07:44", 
"07:45"), counts = c(1358L, 1072L, 112L, 316L, 0L, 16L, 32L, 
0L, 0L, 92L, 80L, 78L, 0L)), row.names = c("1", "2", "3", "4", 
"5", "6", "7", "8", "9", "10", "11", "12", "13"), class = "data.frame")

相关问题