중복 된 행 제거


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

다른 행의 첫 번째 열에 동일한 데이터가 있으므로이 행 중 하나만 원합니다.


3
어느 쪽을 원하세요? 첫 번째? 즉 : 유지하려는 수행 google하거나 localhost또는 hughsie?
Anthony Damico

통계 분석의이 부분은 중요하지 않습니다. 프로젝트 제목 (첫 번째 열), 버그 수 (두 번째 열) 및 프로젝트의 조직 수 (세 번째 열) 만 관련하려고합니다.
user1897691

3
멋있는. 불필요한 열을 버리고? unique를 사용하십시오
Anthony Damico

답변:


186

데이터 프레임을 필요한 열로 분리 한 다음 고유 함수를 사용하십시오.

# 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을
안토니 다 미코

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와 같은 특정 변수에 중복 이있는 경우 플래그를 지정하는 새로운 varibale을 만들고 싶습니다. <-ifelse (이 행 값은 a = 1 열의 이전 행 값 a = 1, 0)
jacob

@jacob이 질문을보십시오 stackoverflow.com/questions/12495345/…
dpel

2
이렇게하면 처음 나타난 값이 유지되고 나머지 복제본은 제거됩니다. 아니면 값을 무작위로 제거합니까?
News_is_Selection_Bias

@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그건 그렇고, 모든 열을 유지할지 여부와 keep에 섞이지 않아야합니다 pandas.
Jason Goal

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

이러한 방법의 또 다른 중요한 기능은 더 큰 데이터 세트에 대한 엄청난 성능 향상입니다

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 Goal

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 데이터베이스를 설정한다는 것은 무엇을 의미합니까? 'sqldf를 사용하면 사용자는 다음을 수행하지 않아도됩니다. 데이터베이스 설정, 각 테이블을 정의하는 create table 문 작성, 데이터베이스로 가져 오기 및 내보내기 '. 최적의 솔루션은 아니지만 SQL에 익숙한 사용자에게는 편리합니다.
mpalanco

3

또는 열 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]>

통계 분석을 위해 col 2 및 3 복제본이 제거되었지만 col 4 및 5 데이터를 tibble로 유지하고을 사용하여 언제든지 원래 데이터 프레임으로 돌아갈 수 있습니다 unnest().


1

데이터 프레임의 중복 행 제거

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


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.