Удалить повторяющиеся строки

Я прочитал CSV файл в R data.frame. В некоторых строках один и тот же элемент находится в одном из столбцов. Я хочу удалить повторяющиеся строки в этом столбце. Например:

platform_external_dbus          202           16                     google        1
platform_external_dbus          202           16         space-ghost.verbum        1
platform_external_dbus          202           16                  localhost        1
platform_external_dbus          202           16          users.sourceforge        8
platform_external_dbus          202           16                    hughsie        1

Мне нужна только одна из этих строк, так как в остальных столбцах в первом столбце одинаковые данные.


person user1897691    schedule 20.12.2012    source источник
comment
какой вы хотите? только первый? другими словами: вы хотите сохранить google, localhost или hughsie?   -  person Anthony Damico    schedule 20.12.2012
comment
Это не имеет значения для этой части моего статистического анализа. Я только пытаюсь связать название проекта (первый столбец), количество ошибок (второй столбец) и количество организаций в проекте (третий столбец).   -  person user1897691    schedule 20.12.2012
comment
Круто. выбросьте ненужные столбцы и используйте? unique   -  person Anthony Damico    schedule 20.12.2012


Ответы (11)


просто изолируйте свой фрейм данных по нужным столбцам, а затем используйте уникальную функцию: D

# in the above example, you only need the first three columns
deduped.data <- unique( yourdata[ , 1:3 ] )
# the fourth column no longer 'distinguishes' them, 
# so they're duplicates and thrown out.
person Anthony Damico    schedule 20.12.2012
comment
Похоже, все будет работать отлично. Не могли бы вы объяснить мне, что происходит с [,1:3] частью этого кода? Я новичок в R, поэтому я спрашиваю, что я могу только предположить, это очевидный вопрос. - person user1897691; 20.12.2012
comment
@ user1897691 отметьте это как правильное;) посмотрите это и, если хотите, отметьте twotorials.com - person Anthony Damico; 20.12.2012
comment
Обратите внимание, что это приведет к удалению всех столбцов, кроме трех первых. - person GuillaumeL; 01.04.2019

Для людей, которые пришли сюда, чтобы найти общий ответ для удаления повторяющихся строк, используйте !duplicated():

a <- c(rep("A", 3), rep("B", 3), rep("C",2))
b <- c(1,1,2,4,1,1,2,2)
df <-data.frame(a,b)

duplicated(df)
[1] FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE  TRUE

> df[duplicated(df), ]
  a b
2 A 1
6 B 1
8 C 2

> df[!duplicated(df), ]
  a b
1 A 1
3 A 2
4 B 4
5 B 1
7 C 2

Ответ от: Удаление повторяющихся строк из фрейма данных R

person Mehdi Nellen    schedule 24.02.2014
comment
Я хочу создать новую переменную, которая помечает наличие дубликата в определенной переменной почти как df $ duplicates ‹- ifelse (это значение строки в столбце a == предыдущее значение строки в столбце a, 1, 0) - person jacob; 22.07.2015
comment
@jacob см. этот вопрос stackoverflow.com/questions/12495345/ - person dpel; 23.05.2016
comment
Это сохраняет первое появившееся значение и удаляет остальные дубликаты, верно? Или убирает значения случайным образом? - person News_is_Selection_Bias; 07.08.2017
comment
@alphabetagamma да, он сохраняет первое появившееся значение - person Mehdi Nellen; 31.01.2019
comment
Если вас интересуют только дубликаты в определенных столбцах, скажем, в столбцах 1 и 2, мы можем использовать df[!duplicated(df[, 1:2])] - person qwr; 03.06.2019

Функция distinct() в _ 2_ выполняет произвольное удаление дубликатов либо из определенных столбцов / переменных (как в этом вопросе), либо с учетом всех столбцов / переменных. dplyr является частью tidyverse.

Данные и пакет

library(dplyr)
dat <- data.frame(a = rep(c(1,2),4), b = rep(LETTERS[1:4],2))

Удалите строки, повторяющиеся в определенном столбце (например, columna)

Обратите внимание, что .keep_all = TRUE сохраняет все столбцы, иначе будет сохранен только столбец a.

distinct(dat, a, .keep_all = TRUE)

  a b
1 1 A
2 2 B

Удалите строки, которые полностью дублируют другие строки:

distinct(dat)

  a b
1 1 A
2 2 B
3 1 C
4 2 D
person Sam Firke    schedule 29.05.2015
comment
Кстати, отличный ответ .keep_all в том, следует ли сохранять все столбцы, а не смешивать их с keep в pandas. - person Jason Goal; 23.07.2019

Пакет data.table также имеет собственные методы unique и duplicated с некоторыми дополнительными функциями.

Оба метода unique.data.table и duplicated.data.table имеют дополнительный аргумент by, который позволяет передавать вектор character или integer имен столбцов или их местоположений соответственно.

library(data.table)
DT <- data.table(id = c(1,1,1,2,2,2),
                 val = c(10,20,30,10,20,30))

unique(DT, by = "id")
#    id val
# 1:  1  10
# 2:  2  10

duplicated(DT, by = "id")
# [1] FALSE  TRUE  TRUE FALSE  TRUE  TRUE

Еще одна важная особенность этих методов - огромный прирост производительности для больших наборов данных.

library(microbenchmark)
library(data.table)
set.seed(123)
DF <- as.data.frame(matrix(sample(1e8, 1e5, replace = TRUE), ncol = 10))
DT <- copy(DF)
setDT(DT)

microbenchmark(unique(DF), unique(DT))
# Unit: microseconds
#       expr       min         lq      mean    median        uq       max neval cld
# unique(DF) 44708.230 48981.8445 53062.536 51573.276 52844.591 107032.18   100   b
# unique(DT)   746.855   776.6145  2201.657   864.932   919.489  55986.88   100  a 


microbenchmark(duplicated(DF), duplicated(DT))
# Unit: microseconds
#           expr       min         lq       mean     median        uq        max neval cld
# duplicated(DF) 43786.662 44418.8005 46684.0602 44925.0230 46802.398 109550.170   100   b
# duplicated(DT)   551.982   558.2215   851.0246   639.9795   663.658   5805.243   100  a 
person David Arenburg    schedule 17.03.2016

Вы также можете использовать distinct() функцию dplyr! Как правило, это более эффективно, чем альтернативные варианты, особенно если у вас есть множество наблюдений.

distinct_data <- dplyr::distinct(yourdata)
person Samantha Karlaina Rhoads    schedule 23.08.2018
comment
Это тот же ответ, что и ответ Сэма Фирке, но с меньшей детализацией. - person qwr; 03.06.2019

общий ответ может быть, например:

df <-  data.frame(rbind(c(2,9,6),c(4,6,7),c(4,6,7),c(4,6,7),c(2,9,6))))



new_df <- df[-which(duplicated(df)), ]

выход:

      X1 X2 X3
    1  2  9  6
    2  4  6  7
person Amit Gupta    schedule 23.12.2017
comment
Будьте осторожны при использовании -which, это приведет к ошибке, если нет дубликатов, использование df[!(duplicated(df)), ] может быть более безопасным. - person Jason Goal; 19.01.2019

С sqldf:

# Example by Mehdi Nellen
a <- c(rep("A", 3), rep("B", 3), rep("C",2))
b <- c(1,1,2,4,1,1,2,2)
df <-data.frame(a,b)

Решение:

 library(sqldf)
    sqldf('SELECT DISTINCT * FROM df')

Выход:

  a b
1 A 1
2 A 2
3 B 4
4 B 1
5 C 2
person mpalanco    schedule 24.06.2015
comment
Это накладные расходы на настройку всей базы данных SQL. cran.r-project.org/web/packages/sqldf/index. html - person qwr; 29.11.2018
comment
Что вы имеете в виду, говоря о создании всей базы данных SQL? Это одно из основных преимуществ: «с sqldf пользователь освобождается от следующих действий, которые выполняются автоматически: настройка базы данных, запись оператора create table, который определяет каждую таблицу, импорт и экспорт в базу данных и из нее. '. Это не оптимальное решение, но удобно для тех, кто знаком с SQL. - person mpalanco; 30.11.2018

Или вы можете вложить данные в столбцах 4 и 5 в одну строку с tidyr:

library(tidyr)
df %>% nest(V4:V5)

# A tibble: 1 × 4
#                      V1    V2    V3             data
#                  <fctr> <int> <int>           <list>
#1 platform_external_dbus   202    16 <tibble [5 × 2]>

Дубликаты столбцов 2 и 3 теперь удалены для статистического анализа, но вы сохранили данные столбцов 4 и 5 в тиббле и можете вернуться к исходному фрейму данных в любой момент с помощью unnest().

person Joe    schedule 22.10.2016

Вот очень простое и быстрое _1 _ / _ 2_ решение:

Удалите полностью одинаковые строки:

library(dplyr)
iris %>% 
  distinct(.keep_all = TRUE)

Удалите строки, которые совпадают только в определенных столбцах:

iris %>% 
  distinct(Sepal.Length, Sepal.Width, .keep_all = TRUE)

person stevec    schedule 02.05.2020

Удалите повторяющиеся строки фрейма данных

library(dplyr)
mydata <- mtcars

# Remove duplicate rows of the dataframe
distinct(mydata)

В этом наборе данных нет ни одной повторяющейся строки, поэтому он вернул то же количество строк, что и в mydata.



Удаление повторяющихся строк на основе одной переменной

library(dplyr)
mydata <- mtcars

# Remove duplicate rows of the dataframe using carb variable
distinct(mydata,carb, .keep_all= TRUE)

Функция .keep_all используется для сохранения всех других переменных в кадре выходных данных.



Удаление повторяющихся строк на основе нескольких переменных

library(dplyr)
mydata <- mtcars

# Remove duplicate rows of the dataframe using cyl and vs variables
distinct(mydata, cyl,vs, .keep_all= TRUE)

Функция .keep_all используется для сохранения всех других переменных в кадре выходных данных.

(от: http://www.datasciencemadesimple.com/remove-duplicate-rows-r-using-dplyr-distinct-function/)

person vasili111    schedule 17.10.2019

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

Используя базу R:

subset(df, ave(V2, V1, FUN = seq_along) == 1)

#                      V1  V2 V3     V4 V5
#1 platform_external_dbus 202 16 google  1

In dplyr

library(dplyr)
df %>% group_by(V1) %>% slice(1L)

Или используя data.table

library(data.table)
setDT(df)[, .SD[1L], by = V1]

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

данные

df <- structure(list(V1 = structure(c(1L, 1L, 1L, 1L, 1L), 
.Label = "platform_external_dbus", class = "factor"), 
V2 = c(202L, 202L, 202L, 202L, 202L), V3 = c(16L, 16L, 16L, 
16L, 16L), V4 = structure(c(1L, 4L, 3L, 5L, 2L), .Label = c("google", 
"hughsie", "localhost", "space-ghost.verbum", "users.sourceforge"
), class = "factor"), V5 = c(1L, 1L, 1L, 8L, 1L)), class = "data.frame", 
row.names = c(NA, -5L))
person Ronak Shah    schedule 19.11.2019