Игнорировать второй или более последовательных 0 - PullRequest
0 голосов
/ 11 января 2019

Я пытаюсь решить самый простой пример и пытаюсь извлечь следующие данные:

count   SN  data.stamp 
1   00601   2018-07-26 13:38:39       
0   00601   2018-11-05 23:00:09       
0   00601   2018-11-05 23:00:16        
4   00601   2018-11-12 23:00:05        
0   00601   2018-12-12 23:00:05        
5   00601   2018-11-12 23:00:05        
0   00601   2018-12-12 23:00:05
0   00601   2018-11-12 23:00:05        
0   00601   2018-12-12 23:00:05

Ожидаемый результат:

count   SN  data.stamp 
1   00601   2018-07-26 13:38:39       
0   00601   2018-11-05 23:00:09       
4   00601   2018-11-12 23:00:05        
0   00601   2018-12-12 23:00:05        
5   00601   2018-11-12 23:00:05        
0   00601   2018-12-12 23:00:05

Я хотел бы рассмотреть только один счет со значением 0. Если имеется несколько значений 0, то следует учитывать только первое значение и игнорировать остальные значения 0.

По сути, я ищу только первое нулевое значение, за которым следует ненулевое значение.

Я пытался использовать rle, но я хотел бы извлечь данные из data.frame. rle может дать мне информацию о значениях и длинах. Я могу написать for цикл, чтобы проверить, но ищу быстрый и короткий путь.

Ответы [ 2 ]

0 голосов
/ 11 января 2019

В базе R вы можете поднастроить свой data.frame, чтобы получить только те строки, для которых count отличается от 0 или count равно 0, но предыдущая строка отличалась от нуля:

df[df$count!=0 | (df$count==0 & c(TRUE, head(df$count, -1)!=0)), ]
# (or: subset(df, count!=0 | (count==0 & c(TRUE, head(count, -1)!=0))))

#  count  SN          data.stamp
#1     1 601 2018-07-26 13:38:39
#2     0 601 2018-11-05 23:00:09
#4     4 601 2018-11-12 23:00:05
#5     0 601 2018-12-12 23:00:05
#6     5 601 2018-11-12 23:00:05
#7     0 601 2018-12-12 23:00:05
0 голосов
/ 11 января 2019

Мы можем использовать rleid из data.table, чтобы создать логический вектор для filter в строках

library(dplyr)
df1 %>%
   filter(!duplicated(cbind(data.table::rleid(count), SN)))

Точнее, rleid можно применить к логическому вектору

df1 %>% 
  filter(!duplicated(cbind(rleid(count== 0), SN)))

rleid проверяет смежные элементы на сходство, а при наличии неравенства увеличивает идентификатор, созданный на 1. т. Е.

v1 <- c(1, 0, 0, 5, 4, 5, 5)
rleid(v1)
#[1] 1 2 2 3 4 5 5

Теперь всем соседним дублирующимся элементам присваивается одинаковый идентификатор. Если мы определенно распознаем '0' как дубликаты

rleid(v1 == 0)
#[1] 1 2 2 3 3 3 3

Здесь есть только два значения, т.е. TRUE/FALSE

v1 == 0
#[1] FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE

Обтекание duplicated возвращает логический индекс для индекса


Если нам нужно решение base R, это можно сделать с помощью rle. Создайте последовательность с репликацией values с lengths и получите логический вектор, обернув duplicated, как и раньше

i1 <- with(rle(!df1$count), rep(seq_along(values), lengths))
i2 <- !duplicated(cbind(i1, df1$SN))
df1[i2, ]
#  count  SN          data.stamp
#1     1 601 2018-07-26 13:38:39
#2     0 601 2018-11-05 23:00:09
#4     4 601 2018-11-12 23:00:05
#5     0 601 2018-12-12 23:00:05
#6     5 601 2018-11-12 23:00:05
#7     0 601 2018-12-12 23:00:05

данные

df1 <- structure(list(count = c(1L, 0L, 0L, 4L, 0L, 5L, 0L, 0L, 0L), 
    SN = c(601L, 601L, 601L, 601L, 601L, 601L, 601L, 601L, 601L
    ), data.stamp = c("2018-07-26 13:38:39", "2018-11-05 23:00:09", 
    "2018-11-05 23:00:16", "2018-11-12 23:00:05", "2018-12-12 23:00:05", 
    "2018-11-12 23:00:05", "2018-12-12 23:00:05", "2018-11-12 23:00:05", 
    "2018-12-12 23:00:05")), class = "data.frame", row.names = c(NA, 
-9L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...