Удаление дубликатов, где связь ясна только путем сравнения строк (относительная ссылка в R) - PullRequest
0 голосов
/ 20 мая 2019

Ситуация: У меня есть некоторые данные о контрактах и ​​о том, сколько акров покрыто контрактом в данном году.Контракты, с которыми я имею дело, имеют отвратительное соглашение об именах, которое заключается в том, что продления контрактов имеют то же имя, что и «a», «b», «c» и т. Д., Добавленные после номера.

Поскольку контракты могут быть возобновлены в любое время, расчет площади за определенный год означает, что при возобновлении счета учитывается дважды.Некоторые примеры данных могут помочь объяснить:

example <- data.frame(contract = c('c300a', 'c300b'),
                      true_contract = c('c300', 'c300'),
                      acres_2007 = c(100, 0),
                      acres_2008 = c(100, 100),
                      acres_2009 = c(0, 100)
)
print(example)

  contract true_contract acres_2007 acres_2008 acres_2009
1    c300a          c300        100        100          0
2    c300b          c300          0        100        100

Как вы можете видеть, если переход от 300a к 300b произошел (например) 20 мая 2008 года, то существует двойной счетв 2008 году. Эти 100 акров - это один и тот же участок земли.Я хотел бы получить способ удалить одну из сотен - не важно, какой, поскольку оба контракта функционально "одинаковы".

Я могу сказать о проблеме, посмотрев на нее, но совершенно озадачен тем, как бы я решил проблему, используя R.На самом деле, я всегда был в растерянности относительно того, как справляться с проблемами данных, когда отношения ясны только из взгляда на линии, которые находятся рядом друг с другом.Это очень стиль мышления в стиле Excel (относительная ссылка), но я не очень хорош в Excel / VBA.Кроме того, я сталкиваюсь с такими проблемами достаточно часто, и мне очень помогло бы выяснить, как сопоставить эту проблему с решениями R.

Ответы [ 2 ]

1 голос
/ 20 мая 2019

Вот общее решение, которое применяет правило ко всем контрактам за все годы. Правило, которое я использовал, было «Для каждого контрактного года с более чем одним контрактом сохраняйте самый большой, а если их больше одного, сохраняйте более поздний».

library(dplyr); library(tidyr)

example %>%
  # Split contract name into two, putting last letter/digit into new column
  separate(contract, c("contract", "renewal_ltr"), sep = -1) %>%

  # Gather into long form to make counting easier
  gather(year_col, acres, -c(contract:true_contract)) %>%

  # Optional: extract year from year_col; dropped below but might be of use.
  mutate(year = readr::parse_number(year_col)) %>%

  # For contracts with more than one value in a year, keep the larger one, 
  #   or if tied, keep the later one
  group_by(contract, year_col) %>%
  arrange(year, desc(acres), desc(renewal_ltr)) %>%
  slice(1) %>%   # Keep top row per group
  ungroup() %>%

  # Optional: spread back
  select(-year) %>%
  spread(year_col, acres, fill = 0)

выход

# A tibble: 2 x 6
  contract renewal_ltr true_contract acres_2007 acres_2008 acres_2009
  <chr>    <chr>       <fct>              <dbl>      <dbl>      <dbl>
1 c300     a           c300                 100          0          0
2 c300     b           c300                   0        100        100
1 голос
/ 20 мая 2019

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

example$acres_2008 <- ave(
  example$acres_2008, 
  example$true_contract, 
  FUN = function(a) replace(a, duplicated(a), 0)
)

Результат с вашим примером:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...