Удалить повторяющиеся строки с определенным значением в столбце Speci c - PullRequest
1 голос
/ 27 марта 2020

У меня есть фрейм данных, и я хочу удалить строки, которые дублируются во всех столбцах, кроме одного, и выбрать сохранение тех, которые не имеют определенных значений.

enter image description here

В приведенном выше примере 3-я строка и 4-я строка дублируются для всех столбцов, кроме столбца col3, поэтому я хочу сохранить только одну строку. Сложный шаг - я хочу сохранить 4-ю строку вместо 3-й, потому что 3-я строка в col3 «исключена». В общем, я хочу сохранить только те строки (которые были продублированы), которые не были "исключены".

У моего реального фрейма данных есть много дублированных строк, и среди этих двух строк, которые дублируются, одна из них наверняка "исключена".

Ниже приведен повторный вывод, например:

a <- c(1,2,3,3,7)
b <- c(4,5,6,6,8)
c <- c("red","green","excluded","orange","excluded")
d <- data.frame(a,b,c)

Большое спасибо!

Обновление: или, удаляя дубликаты, сохраняйте только второе наблюдение (4-й ряд).

Ответы [ 5 ]

0 голосов
/ 29 марта 2020

Относительно вашего редактирования в конце вопроса:

Обновление: или, при удалении дубликата, оставляйте только второе наблюдение (4-й ряд).

примечание что в случае, если упорядочение строк по col3 определяет, что строка , которую нужно сохранить, всегда является последней среди повторяющихся записей, вы можете просто установить fromLast=TRUE в функции duplicated() для запроса что строки должны быть помечены как дубликаты , начиная отсчет дубликатов с последней найденной для каждой дублирующейся группы.

Использование слегка измененной версии ваших данных (где я добавил больше дублирующих групп, чтобы лучше покажите, что процесс работает в более общем случае):

a <- c(1,1,2,3,3,3,7)
b <- c(4,4,5,6,6,6,8)
c <- c("excluded", "red","green","excluded", "excluded","orange","excluded")
d <- data.frame(a,b,c)

  a b        c
1 1 4 excluded
2 1 4      red
3 2 5    green
4 3 6 excluded
5 3 6 excluded
6 3 6   orange
7 7 8 excluded

, используя:

ind2remove = duplicated(d[,c("a", "b")], fromLast=TRUE)
(d_noduplicates = d[!ind2remove,])

, мы получаем:

  a b        c
2 1 4      red
3 2 5    green
6 3 6   orange
7 7 8 excluded

Обратите внимание, что это не так требуется, чтобы строки в каждой дублирующейся группе были все вместе в исходных данных. Единственная важная вещь - это то, что вы хотите сохранить запись, отображающуюся последней в данных из каждой дублирующейся группы.

0 голосов
/ 27 марта 2020

Немного сокращая подход @Klone, еще одно решение dplyr:

d %>% mutate(c = factor(c, ordered = TRUE, 
                        levels = c("red", "green", "orange", "excluded"))) %>% # Order the factor variable
  arrange(c) %>% # Sort the data frame so that excluded comes first
  group_by(a, b) %>% # Group by the two columns that determine duplicates
  mutate(id = 1:n()) %>% # Assign IDs in each group
  filter(id == 1) # Only keep one row in each group

Результат:

# A tibble: 4 x 4
# Groups:   a, b [4]
      a     b c           id
  <dbl> <dbl> <ord>    <int>
1     1     4 red          1
2     2     5 green        1
3     3     6 orange       1
4     7     8 excluded     1
0 голосов
/ 27 марта 2020

Вот пример с al oop:

a <- c(1,2,3,3,7)
b <- c(4,5,6,6,8)
c <- c("red","green","excluded","orange","excluded")
d<- data.frame(a,b,c)

# Give row indices of duplicated rows (only the second and more occurence are given)
duplicated_rows=which(duplicated(d[c("a","b")]))

to_remove=c()
# Loop over different duplicated rows
for(i in duplicated_rows){
  # Find simmilar rows
  selection=which(d$a==d$a[i] & d$b==d$b[i])
  # Sotre indices of raw in the set of duplicated row whihc are "excluded"
  to_remove=c(to_remove,selection[which(d$c[selection]=="excluded")])
}

# Remove rows
d=d[-to_remove,]

print(d)

> a b       c
> 1 4      red
> 2 2 5   green
> 4 3 6   orange
> 5 7 8  excluded

0 голосов
/ 27 марта 2020

Вот такая возможность ... Надеюсь, это поможет:)

nquit <- (d %>%
  mutate(code= 1:nrow(d)) %>%
  group_by(a, b) %>%
  mutate(nDuplicate= n()) %>%
  filter(nDuplicate > 1) %>%
  filter(c == "excluded"))$code

e <- d[-nquit]
0 голосов
/ 27 марта 2020

dplyr с некоторой базой R должно работать для этого:

 library(dplyr) 
 a <- c(1,2,3,3,3,7)
 b <- c(4,5,6,6,6,8)
 c <- c("red","green","brown","excluded","orange","excluded")
 d <- data.frame(a,b,c)

 d <- filter(d, !duplicated(d[,1:2]) | c!="excluded")

Result: 
  a b        c
1 1 4      red
2 2 5    green
3 3 6    brown
4 3 6   orange
5 7 8 excluded

Фильтр избавится от всего, что должно быть исключено и не дублировано. Я добавил пример неуникального исключения в ваш пример («коричневый») для проверки.

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