重複した行を削除する


152

私は読んで持っているCSVRの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

他の行の最初の列に同じデータがあるため、これらの行の1つだけを希望します。


3
あなたはどれが欲しいですか?最初だけ?つまり、「googleor localhostor or 」を保持しますかhughsie
アンソニーダミコ

私の統計分析のこの部分では問題ではありません。プロジェクトのタイトル(1列目)、バグの数(2列目)、プロジェクトの組織数(3列目)のみを関連付けようとしています。
user1897691

3
涼しい。不要な列を捨てて?uniqueを使用する
Anthony Damico

回答:


186

データフレームを必要な列に分離し、独自の関数を使用する: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.

1
これは完全に機能するようです。[,1:3]そのコードの一部で何が起こっているのか説明してください。私はRの初心者です。そのため、自分にしか想定できないことは明らかな質問です。
user1897691

6
@ user1897691正しいものとしてマークしてください;) これ見て、気に入った場合は、twotorials.comを
Anthony Damico

3
これにより、最初の3つの列を除くすべての列が削除されることに注意してください。
GuillaumeL

186

重複する行を削除するための一般的な答えを探すためにここに来た人は、次を使用します!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データフレームから重複行を削除する


df $ duplicates <-ifelse(列aのこの行の値==列aの前の行の値、1、0)のような特定の変数に重複がある場合にフラグを立てる新しい変数を作成したい
jacob


2
これは最初に現れた値を保持し、残りの重複を削除しますよね?または、ランダムに値を削除しますか?
News_is_Selection_Bias 2017

@alphabetagammaはい、最初に表示された値を保持します
Mehdi Nellen

2
列1と列2の特定の列の重複のみに関心がある場合は、次のように使用できますdf[!duplicated(df[, 1:2])]
qwr

82

パッケージdistinct()内の関数は、dplyr(この質問のように)特定の列/変数から、またはすべての列/変数を考慮して、任意の重複削除を実行します。dplyrの一部ですtidyverse

データとパッケージ

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

特定の列(たとえば、column a)で重複する行を削除する

.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

偉大な答えは、途中で、.keep_allと混合してはならない、すべての列を保持するかどうかのためにあるkeeppandas
Jasonゴール

28

data.tableパッケージには、持っているuniqueduplicated、それの方法はいくつかの追加機能を備えた独自のです。

どちらunique.data.tableduplicated.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

これらの方法のもう1つの重要な機能は、より大きなデータセットのパフォーマンスが大幅に向上することです。

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 

7

dplyrdistinct()機能も使えます!特に多くの観測がある場合は、他のオプションよりも効率的になる傾向があります。

distinct_data <- dplyr::distinct(yourdata)

1
これはSam Firkeの回答と同じ回答ですが、詳細はあまりありません。
qwr

6

一般的な答えは、たとえば次のとおりです。

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

1
-which使用するdf[!(duplicated(df)), ]場合は注意が必要です。重複がない場合はエラーが発生します。使用する方が安全な場合があります。
Jasonゴール

5

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

これには、SQLデータベース全体を設定するオーバーヘッドがあります。cran.r-project.org/web/packages/sqldf/index.html
qwr

SQLデータベース全体をセットアップするとはどういう意味ですか?これは主な利点の1つです。「sqldfを使用すると、ユーザーは次のことを行う必要がなくなります。これらはすべて自動的に行われます。データベースのセットアップ、各テーブルを定義するcreate tableステートメントの作成、データベースへのインポートおよびデータベースからのエクスポート'。これは最適なソリューションではありませんが、SQLに慣れているユーザーにとっては便利です。
mpalanco 2018年

3

または、列4と5のデータを次のように1つの行にネストすることもできます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]>

col 2と3の重複は統計分析のために削除されましたが、col 4と5のデータはティブルに保持されているので、を使用していつでも元のデータフレームに戻ることができunnest()ます。


1

データフレームの重複する行を削除する

library(dplyr)
mydata <- mtcars

# Remove duplicate rows of the dataframe
distinct(mydata)

このデータセットでは、重複する行は1つではないため、mydataと同じ数の行が返されました。



1つの変数に基づいて重複行を削除する

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/


0

この問題は、各グループから最初の行を選択することによっても解決できます。グループは、一意の値を選択する基準となる列です(共有の例では、最初の列です)。

ベースRの使用:

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

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

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

0

非常にシンプルで高速なdplyr/ tidyソリューションを次に示します。

まったく同じ行を削除します。

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

特定の列のみが同じである行を削除します。

iris %>% 
  distinct(Sepal.Length, Sepal.Width, .keep_all = TRUE)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.