Как написать код R для удаления дубликатов строк, где одно наблюдение является отрицательным значением дубликата? - PullRequest
1 голос
/ 18 июня 2019

У меня есть некоторые данные о продажах, в которых ошибки, зарегистрированные в торговой точке, исправляются впоследствии, и набор данных по-прежнему содержит записи для первоначальной ошибки, а затем дубликат ошибки, но с отрицательным значением цены. Как я могу удалить эти наблюдения условно, чтобы «если цена <0, удалить наблюдение и соответствующее наблюдение, где цена = цена * -1, дата = дата, тип = тип, вес = вес» </p>

Данные структурированы как

Date      Type     Weight     Price
5/5/16    A        15         34
5/5/16    A        15         -34
5/5/16    B        15         43

Другая проблема заключается не только в том, что отредактированные ошибки существуют в виде дубликатов, но и в типе, весе и ценовых записях есть несколько действительных дубликатов. например продажа может быть сделана в тот же день за 10 предметов типа А по 15 фунтов каждая за 34 доллара. - Я добавил столбец для подсчета количества дубликатов абсолютных значений test2 <- test%>% dplyr :: group_by (Дата, Тип, Вес, ABS_Price)%>% dplyr :: mutate (replicate = seq (n ()) )) так как бы я закодировал 'если наблюдение имеет цену <0, то удалите наблюдение, где replicate = x-1' </p>

Ответы [ 4 ]

2 голосов
/ 18 июня 2019

Одно простое dplyr решение.Группируйте строки по комбинации клавиш, которые определяют дубликат (обратите внимание, что мы можем применять преобразования к столбцам на лету) и фильтруйте одноэлементные группы.

library(dplyr)

with.dups <- read.csv(...)
without.dups <- with.dups %>% 
    group_by(Date, Type, Weight, abs(Price)) %>% 
    filter(n()==1) %>%
    as.data.frame  # you can omit this part if you don't need to transform the resulting tibble table to a vanilla data.frame

Тестовые данные.

Date,Type,Weight,Price
5/5/16,A,15,34
5/5/16,A,15,-34
5/5/16,B,15,43

Тестовый вывод

    Date Type Weight Price abs(Price)
1 5/5/16    B     15    43         43
1 голос
/ 18 июня 2019

Я добавил дополнительную строку в ваш пример, чтобы отследить вероятный крайний случай двух транзакций с совпадающими ключами - мы, вероятно, хотим удалить только первое совпадение.

df <- read.table(
  header = T, 
  stringsAsFactors = F,
  text = "Date      Type     Weight     Price
5/5/16    A        15         34
5/5/16    A        15         34
5/5/16    A        15         -34
5/5/16    B        15         43")

Мой подход заключается в том, чтобыищите совпадения, где все одинаково (в том числе # транзакции с этими значениями ключа), но цена перевернута.Если это так, сократить:

library(dplyr)
df2 <- df %>%
  group_by(Date, Type, Weight, Price) %>%
  mutate(repeat_count = row_number()) %>%
  ungroup()

left_join(df2,
          df2 %>% mutate(Price = -Price, cut_flag = FALSE)) %>%
  filter(is.na(cut_flag)) %>%
  select(-cut_flag)

# A tibble: 2 x 5
  Date   Type  Weight Price repeat_count
  <chr>  <chr>  <int> <int>        <int>
1 5/5/16 A         15    34            2
2 5/5/16 B         15    43            1
0 голосов
/ 18 июня 2019

немного отличается от Ronak, но похожая предпосылка с использованием which ()

df$price <- abs(df$price)  #take absolute value, making all entries positive

dups <- which(duplicated(df)) #find place of duplicates, where all columns match


newdf <- df[-c(dups-1,dups),] 

Все дубликаты удалены, и непосредственно перед каждым дубликатом также

0 голосов
/ 18 июня 2019

Мы можем сделать это в базе R, используя duplicated. Использование данных @Jon Spring

df[!((duplicated(df[1:3]) | duplicated(df[1:3], fromLast = TRUE)) & 
     (duplicated(abs(df$Price)) | duplicated(abs(df$Price), fromLast = TRUE))), ]

#    Date Type Weight Price
#4 5/5/16    B     15    43

Предполагается, что у вас есть Date, Type и Weight в столбце 1:3 соответственно. Если их положение не зафиксировано, вы также можете выбрать их по имени

df[!((duplicated(df[c("Date", "Type", "Weight")]) | 
      duplicated(df[c("Date", "Type", "Weight")], fromLast = TRUE)) & 
      (duplicated(abs(df$Price)) | duplicated(abs(df$Price), fromLast = TRUE))), ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...