Verwijder dubbele rijen

Ik heb een CSV-bestand ingelezen in een R data.frame. Sommige rijen hebben hetzelfde element in een van de kolommen. Ik wil graag rijen verwijderen die duplicaten zijn in die kolom. Bijvoorbeeld:

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

Ik wil slechts één van deze rijen omdat de andere dezelfde gegevens in de eerste kolom hebben.


Antwoord 1, autoriteit 100%

Isoleer gewoon je dataframe tot de kolommen die je nodig hebt en gebruik dan de unieke functie 😀

# 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.

Antwoord 2, autoriteit 96%

Voor mensen die hier zijn gekomen om een algemeen antwoord te zoeken voor het verwijderen van dubbele rijen, gebruik !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

Antwoord van: Dubbele rijen verwijderen uit R-dataframe


Antwoord 3, autoriteit 48%

De functie distinct()in de dplyrpakket voert willekeurige dubbele verwijdering uit, ofwel van specifieke kolommen/variabelen (zoals in deze vraag) of rekening houdend met alle kolommen/variabelen. dplyrmaakt deel uit van de tidyverse.

Gegevens en pakket

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

Verwijder rijen die zijn gedupliceerd in een specifieke kolom (bijv. koloma)

Merk op dat .keep_all = TRUEalle kolommen behoudt, anders blijft alleen kolom abehouden.

distinct(dat, a, .keep_all = TRUE)
  a b
1 1 A
2 2 B

Verwijder rijen die volledige duplicaten zijn van andere rijen:

distinct(dat)
  a b
1 1 A
2 2 B
3 1 C
4 2 D

Antwoord 4, autoriteit 14%

Het data.tablepakket heeft ook zijn eigen uniqueen duplicatedmethoden met enkele extra functies.

zowel de unique.data.tableen de duplicated.data.tablemethoden hebben een extra byargument waarmee u een kunt passeren characterof integervector van kolomnamen of hun locaties respectievelijk

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

Een andere belangrijke functie van deze methoden is een enorme prestatieverstart voor grotere datasets

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 

5, Autoriteit 4%

Het algemene antwoord kan zijn
Bijvoorbeeld:

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

OUTPUT:

     X1 X2 X3
    1  2  9  6
    2  4  6  7

6, Autoriteit 3%

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

Oplossing:

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

Uitgang:

 a b
1 A 1
2 A 2
3 B 4
4 B 1
5 C 2

7

of u zou de gegevens in Cols 4 en 5 kunnen nestelen in een enkele rij met 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]>

De COL 2 en 3 duplicaten worden nu verwijderd voor statistische analyse, maar u hebt de COL 4 en 5 gegevens in een tibbel gehouden en kan op elk punt met unnest().


8

Hier is een heel eenvoudige, snel dplyr/ tidyoplossing:

rijen verwijderen die volledig hetzelfde zijn:

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

rijen verwijderen die niet alleen in bepaalde kolommen zijn:

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

9

Verwijder dubbele rijen van een dataframe

library(dplyr)
mydata <- mtcars
# Remove duplicate rows of the dataframe
distinct(mydata)

In deze dataset is er geen enkele dubbele rij, dus het retourneerde hetzelfde aantal rijen zoals in MyData.

Verwijder dubbele rijen op basis van een één variabele

library(dplyr)
mydata <- mtcars
# Remove duplicate rows of the dataframe using carb variable
distinct(mydata,carb, .keep_all= TRUE)

De functie .keep_all wordt gebruikt om alle andere variabelen in het uitgangsgegevens te behouden.

Verwijder dubbele rijen op basis van meerdere variabelen

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

De .keep_allFunctie wordt gebruikt om alle andere variabelen in het uitvoergegevens te behouden.

(van: http: //www.datasciencemadesimple.com/Remove-duplicate-Rows-r-USing-dsyr-distinct-function/ )


10

Dit probleem kan ook worden opgelost door de eerste rij uit elke groep te selecteren waar de groep de kolommen zijn waarop we unieke waarden willen selecteren (in het gedeelde voorbeeld is slechts de 1e kolom).

Gebruik basis 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)

of gebruik het data.table

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

Als we een unieke rijen moeten vinden op basis van meerdere kolommen, voegt u deze kolomnamen toe in groepsdeel voor elk van het bovenstaande antwoord.

gegevens

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

Other episodes