Hapus baris yang digandakan

152

Saya telah membaca CSVfile menjadi R data.frame. Beberapa baris memiliki elemen yang sama di salah satu kolom. Saya ingin menghapus baris yang merupakan duplikat di kolom itu. Sebagai contoh:

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

Saya ingin hanya satu baris ini karena yang lain memiliki data yang sama di kolom pertama.

pengguna1897691
sumber
3
yang mana yang kamu mau? hanya yang pertama? dengan kata lain: Anda ingin menyimpan googleatau localhostatau hughsie?
Anthony Damico
Tidak masalah untuk bagian analisis statistik saya ini. Saya hanya mencoba menghubungkan judul proyek (kolom pertama), jumlah bug (kolom kedua), dan jumlah organisasi pada proyek (kolom ketiga).
user1897691
3
keren. buang kolom yang tidak perlu dan gunakan? unik
Anthony Damico

Jawaban:

186

cukup isolasi frame data Anda ke kolom yang Anda butuhkan, lalu gunakan fungsi unik: 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.
Anthony Damico
sumber
1
Ini sepertinya akan bekerja dengan sempurna. Bisakah Anda jelaskan kepada saya apa yang terjadi dengan [,1:3]bagian dari kode itu? Saya baru mengenal R, itulah sebabnya saya bertanya apa yang hanya dapat saya asumsikan adalah pertanyaan yang jelas.
user1897691
6
@ user1897691 tandai sebagai sudah benar;) tonton ini dan jika Anda suka, periksa twotorials.com
Anthony Damico
3
Perhatikan bahwa ini akan menghapus semua kolom kecuali tiga yang pertama.
GuillaumeL
186

Bagi orang-orang yang datang ke sini untuk mencari jawaban umum untuk penghapusan baris rangkap, gunakan !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

Jawaban dari: Menghapus baris yang digandakan dari bingkai data R

Mehdi Nellen
sumber
Saya ingin membuat varibale baru yang menandai jika ada duplikat pada variabel tertentu hampir seperti df $ duplikat <- ifelse (nilai baris ini dalam kolom a == nilai baris sebelumnya di kolom a, 1, 0)
jacob
@ jacob lihat pertanyaan ini stackoverflow.com/questions/12495345/…
dpel
2
Ini menjaga nilai yang muncul pertama dan menghapus sisa duplikat, kan? Atau menghapus nilai secara acak?
News_is_Selection_Bias
@alphabetagamma ya, itu membuat nilai yang muncul pertama
Mehdi Nellen
2
Jika Anda hanya tertarik pada duplikat di kolom tertentu, katakanlah cols 1 dan 2, kita dapat menggunakandf[!duplicated(df[, 1:2])]
qwr
82

Fungsi distinct()dalam dplyrpaket melakukan penghapusan duplikat acak, baik dari kolom / variabel tertentu (seperti dalam pertanyaan ini) atau mempertimbangkan semua kolom / variabel. dplyradalah bagian dari tidyverse.

Data dan paket

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

Hapus baris yang digandakan dalam kolom tertentu (mis., Kolom a)

Perhatikan bahwa .keep_all = TRUEmempertahankan semua kolom, jika tidak hanya kolom yang aakan dipertahankan.

distinct(dat, a, .keep_all = TRUE)

  a b
1 1 A
2 2 B

Hapus baris yang merupakan duplikat lengkap dari baris lain:

distinct(dat)

  a b
1 1 A
2 2 B
3 1 C
4 2 D
Sam Firke
sumber
Jawaban yang bagus, by the way, .keep_alladalah untuk apakah untuk menjaga semua kolom, tidak dicampur dengan keepdi pandas.
Jason Goal
28

The data.tablepaket juga memiliki uniquedan duplicatedmetode itu sendiri dengan beberapa fitur tambahan.

Baik unique.data.tabledan duplicated.data.tablemetode memiliki byargumen tambahan yang memungkinkan Anda untuk lulus characteratau integervektor nama kolom atau lokasi mereka masing-masing

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

Fitur penting lain dari metode ini adalah perolehan kinerja yang sangat besar untuk set data yang lebih besar

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 
David Arenburg
sumber
7

Anda juga dapat menggunakan dplyr's distinct()fungsi! Ini cenderung lebih efisien daripada opsi alternatif, terutama jika Anda memiliki banyak pengamatan.

distinct_data <- dplyr::distinct(yourdata)
Samantha Karlaina Rhoads
sumber
1
Ini adalah jawaban yang sama dengan jawaban Sam Firke, tetapi kurang detail.
qwr
6

jawaban umum dapat misalnya:

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)), ]

keluaran:

      X1 X2 X3
    1  2  9  6
    2  4  6  7
Amit Gupta
sumber
1
Berhati-hatilah saat menggunakan -which, ini akan menyebabkan kesalahan jika tidak ada duplikat, penggunaan df[!(duplicated(df)), ]mungkin lebih aman.
Jason Goal
5

Dengan 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)

Larutan:

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

Keluaran:

  a b
1 A 1
2 A 2
3 B 4
4 B 1
5 C 2
mpalanco
sumber
Ini memiliki overhead pengaturan seluruh database SQL. cran.r-project.org/web/packages/sqldf/index.html
qwr
Apa yang Anda maksud dengan mengatur seluruh database SQL? Itulah salah satu keuntungan utama: 'dengan sqldf pengguna dibebaskan dari keharusan melakukan yang berikut, yang semuanya dilakukan secara otomatis: pengaturan basis data, menulis pernyataan tabel yang mendefinisikan setiap tabel, mengimpor dan mengekspor ke dan dari basis data ' Ini bukan solusi optimal, tetapi berguna bagi mereka yang terbiasa dengan SQL.
mpalanco
3

Atau Anda bisa membuat sarang data dalam cols 4 dan 5 menjadi satu baris dengan 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]>

Duplikat kolom 2 dan 3 sekarang dihapus untuk analisis statistik, tetapi Anda telah menyimpan data kolom 4 dan 5 dalam sebuah tibble dan dapat kembali ke bingkai data asli kapan saja dengan unnest().

Joe
sumber
1

Hapus duplikat baris dataframe

library(dplyr)
mydata <- mtcars

# Remove duplicate rows of the dataframe
distinct(mydata)

Dalam dataset ini, tidak ada satu baris duplikat sehingga menghasilkan jumlah baris yang sama seperti di data saya.



Hapus Baris Duplikat berdasarkan pada satu variabel

library(dplyr)
mydata <- mtcars

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

Fungsi .keep_all digunakan untuk mempertahankan semua variabel lain dalam bingkai data output.



Hapus Baris Duplikat berdasarkan beberapa variabel

library(dplyr)
mydata <- mtcars

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

Fungsi .keep_all digunakan untuk mempertahankan semua variabel lain dalam bingkai data output.

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

vasili111
sumber
0

Masalah ini juga dapat diselesaikan dengan memilih baris pertama dari masing-masing kelompok di mana grup tersebut adalah kolom berdasarkan yang ingin kita pilih nilai-nilai unik (dalam contoh bersama itu hanya kolom 1).

Menggunakan basis R:

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

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

Di dplyr

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

Atau menggunakan data.table

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

Jika kita perlu mencari tahu baris-baris unik berdasarkan beberapa kolom, cukup tambahkan nama kolom itu di bagian pengelompokan untuk masing-masing jawaban di atas.

data

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))
Ronak Shah
sumber
0

Berikut ini adalah solusi yang sangat sederhana, cepat dplyr/ tidy:

Hapus baris yang sepenuhnya sama:

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

Hapus baris yang sama hanya di kolom tertentu:

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