Выявить прерванные наблюдения - PullRequest
0 голосов
/ 27 сентября 2018

Я хотел бы определить отсутствующие наблюдения, которые предполагают ошибки очистки / данных.

Мой фрейм данных состоит из множества учетных записей за многие годы.Вот следующие правила:

  • Счета могут быть созданы или удалены .В этих случаях сумма составляет либо $ 0, либо NA.Такие наблюдения (вероятно) не являются результатом неверных данных.
  • Счета прерваны NA или $ 0, вероятно, являются результатом неверных данных или ошибок очистки.

В приведенных ниже данных счета AE показывают сумму за 2001-2004 годы.

df <- tribble(
       ~account,    ~"2001",     ~"2002",    ~"2003",  ~"2004",
       "Account.A",     100,          90,         87,       80,  #<Good   
       "Account.B",       0,          20,         30,       33,  #<Good
       "Account.C",      50,          55,          0,       0,   #<Good
       "Account.D",     200,         210,         NA,       210, #<Bad
       "Account.E",     150,           0,        212,       211) #<Bad

Счета A, B, C показывают хорошие данные:

  • Учетная запись A отображает непрерывные данные
  • Учетная запись B отображает учетную запись, созданную в 2002 году.
  • Учетная запись C отображает учетную запись, срок действия которой истек в 2003 году и оставалась нулевой в дальнейшем.

Учетные записи D и E показывают неверные данные:

  • Учетная запись D показывает учетную запись, заблокированную в 2003 г.
  • Учетная запись E показывает учетную запись, прерванную в 2002 г.

Моя цель - определить прерванные линии (D, E) и пометить их.

Мне бы хотелось решение, которое можно было бы обобщить на многие годы и тысячи учетных записей.

1 Ответ

0 голосов
/ 28 сентября 2018

Вот вариант tidyverse, который может быть не самым красивым, но с этим справится:

library(tidyverse)
df %>% 
  gather(year, value, `2001`:`2004`) %>% 
  group_by(account) %>% 
  mutate(order = if_else(year == min(year), 'first', 
                         if_else(year == max(year), 'last', 'mid'))) %>% 
  mutate(value = replace(value, is.na(value), 0)) %>% 
  mutate(start0 = row_number() >= min(row_number()[value != 0]),
         end0 = row_number() <= max(row_number()[value != 0])) %>% 
  mutate(check = if_else(order == 'mid' & value == 0 & start0 == TRUE & end0 == TRUE, TRUE, FALSE)) %>% 
  filter(check == TRUE)

# A tibble: 2 x 7
# Groups:   account [2]
  account   year  value order start0 end0  check
  <chr>     <chr> <dbl> <chr> <lgl>  <lgl> <lgl>
1 Account.E 2002      0 mid   TRUE   TRUE  TRUE 
2 Account.D 2003      0 mid   TRUE   TRUE  TRUE 

Вот объяснение:

  • Преобразование данных из широкогодолго
  • По группам определите, является ли запись учетной записи первой, средней или последней записью в своей истории.
  • Поскольку нули и NA обрабатываются одинаково, NA заменяются нулями, чтобы с этим было немного проще работать, но они могут быть сохранены как есть, а код обновлен для их обработки.
  • Добавлены столбцы ИСТИНА / ЛОЖЬ, определяющие, начинается ли последовательность значений 0 с начала или конца истории учетной записи.
  • Если для учетной записи задано значение 0, а не первая или последняя запись, а не часть последовательности 0, запущенная с начала или конца истории учетной записи, учетная запись помечается как ИСТИНА для проверки.
  • Наконец, есть фильтр только для учетных записей, которые необходимо проверить.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...