R 벡터 중복제거 - r begteo jungbogjegeo

R Basic::unique 함수는 많이들 사용을 해보셨을 겁니다.

unique 함수 내에서 아주 유용한 기능이 있어서 하나 소개해드릴까 싶습니다.

그 기능은 다름아닌, fromLast 인데요.

 

이 기능은 unique 함수로 값들을 추릴때, 중복된 값들이 여러개 있으면, 

가장 마지막 행만 남기고 없애는 기능입니다. 

 이 기능을 아주 약간만 응용하면 last visit 이나 first visit 때의 값만을 남기고 모든 중복 측정값을 제거할 수 있습니다.

 

a 라는 data.frame 이 있을 때. visit time 을 vt 라는 변수에 저장해 두었다고 하고, 식별자는 id 라고 가정을 하고

아래의 코드를 입력한다면 어떠한 결과가 나올까요?


a <- a[order(a$vt, decreasing =T), ]
a <- a[ (unique(a$id), fromLast=T), ]


쉽게 예상할 수 있듯이,

vt값 기준으로 내림차순으로 정렬이 될 것이며, fromLast 덕분에 마지막 값만 살아남게 될 것 입니다.

즉, 마지막 visit time 만 남기고 모두 정리가 되겠죠?

반대로 order 를 ascending 으로 한다면, 첫 visit time 만 남기고 모두 사라지게 됩니다.

참 쉽죠 ?

 

** 도움이 되셨다면, '공감 / 댓글' 부탁드립니다^^

공유하기

게시글 관리

구독하기의학통계 with R, feat. 내과의사

저작자표시 비영리 변경금지

'R_statistics > Rs_preparation' 카테고리의 다른 글

[R프로그래밍] 데이터전처리:: log-transformation in R (R에서 로그 변환)  (0)2019.12.25[R프로그래밍] 데이터전처리:: R 에서 package 불러올때 tip  (0)2019.12.12[R프로그래밍] 데이터전처리 intersect:: 벡터에서 중복되는 값 찾기  (0)2019.11.06[R프로그래밍] 데이터전처리 stringr:: 문자, 텍스트, str_split, 변수 이름 나누기,  (1)2019.03.22[R프로그래밍] 4분위 그룹 만들기, quartile grouping  (0)2019.03.18

▼ 왼쪽의 테이블에는 a=3, b=10 인 행이 두 개 존재합니다. a=2, b=20 인 행도 두 개가 있습니다. 이때 중복된 데이터를 하나의 행으로 반환할 수 있도록 오른쪽 테이블과 같이 만들어보겠습니다.

R 벡터 중복제거 - r begteo jungbogjegeo

먼저 다음 코드를 실행하여 위와 같은 데이터를 만듭니다.


> test <- data.frame(a=c(1,2,3,3,3,2,2,1),
					 b=c(10,10,10,10,20,20,20,30))
> test
  a  b
1 1 10
2 2 10
3 3 10
4 3 10
5 3 20
6 2 20
7 2 20
8 1 30
  

중복을 제거하고 유일한 행을 반환하는 방법 세 가지를 알아보겠습니다.

1. duplicated 함수

duplicated 함수는 중복된 요소를 탐색하여 논리적 형태의 벡터로 반환합니다. 다음 예를 확인해보겠습니다. duplicated 함수의 결과값은 TRUE 또는 FALSE 로 반환합니다. 결과값을 보면 네번째와 일곱번째 위치에 TRUE로 나왔습니다. 이는 위 데이터에서 중복된 데이터를 의미합니다. 중복데이터는 TRUE로 반환하고 그 외에는 FALSE를 반환합니다.


> duplicated(test)
[1] FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE
  

TRUE에 해당하는 데이터를 추출하기 위해 대괄호를 이용하여 추출합니다. 아래 코드를 실행하면 중복된 행이 있는 데이터를 반환합니다.


> test[duplicated(test),]
  a  b
4 3 10
7 2 20
  

중복하지 않는 유일한 행을 추출해야하기 때문에 위 코드에서 부정을 의미하는 ! 를 함수 앞에 붙여줍니다. 그러면 아래와 같이 중복된 데이터를 제거한 유일한 행을 반환합니다. duplicated 함수의 결과값은 논리형태의 벡터로 나오기 때문에 실제 결과값을 보기 위해선 인덱싱을 해주어야 합니다.


> test[!duplicated(test),]
  a  b
1 1 10
2 2 10
3 3 10
5 3 20
6 2 20
8 1 30
  

2. unique 함수

unique 함수는 duplicated 함수와 비슷하지만 그 결과값의 형태가 다릅니다. 바로 결과값을 내보내기 때문에 별도의 인덱싱하는 과정이 필요 없습니다.


> unique(test)
  a  b
1 1 10
2 2 10
3 3 10
5 3 20
6 2 20
8 1 30
  

3. distinct 함수

distinct 함수는 dplyr에 속해있는 함수로서 unique 함수와 같은 역할을 합니다. 이 함수를 사용하기 위해선 먼저 dplyr패키지가 설치되어 있어야 합니다.


> # dplyr패키지가 설치되어 있지 않을 시에는 install.packages("dplyr")실행
> library(dplyr)
> distinct(test)
  a  b
1 1 10
2 2 10
3 3 10
4 3 20
5 2 20
6 1 30
  

unique함수와 distinct함수는 같은 역할을 하지만 그 수행속도는 distinct함수가 더 빠르다고 알려져 있습니다. system.time() 함수는 코드를 수행한 시간을 알 수 있는 함수입니다. 각 열에 백 만개의 난수를 발생시켜 유일한 행을 반환해보도록 하겠습니다. 끝 줄에 있는 elapsed time을 보면 distinct 함수는 약 74초, unique함수는 201초가 걸렸다는 것을 의미합니다.

R에서 중복된 행을 삭제하려면 unique()를 사용하면 된다.


다음과 같은 x에서


R 벡터 중복제거 - r begteo jungbogjegeo


unique()를 실행시키면


R 벡터 중복제거 - r begteo jungbogjegeo


중복된 행들이 사라지는 것을 알 수 있다.



중복된 행이 몇 개나 되는지 숫자가 알고 싶을 때는?


지난 번에 본 nrow를 쓰면 되겠다.


R 벡터 중복제거 - r begteo jungbogjegeo


여러 개의 열이 있을 경우에는


행의 모든 값이 완전히 동일할 때만 중복으로 간주한다. 


예를들어 다음과 같은 x에서


R 벡터 중복제거 - r begteo jungbogjegeo


unique()를 실행시키면


R 벡터 중복제거 - r begteo jungbogjegeo


4행과 5행은 서로 중복이 아니므로 제거되지 않는다.



간혹 중복된 행들을 직접 눈으로 확인하고 싶을 때가 있다.


이럴 땐 duplicated() 함수를 사용한다.


다음과 같은 x에서


R 벡터 중복제거 - r begteo jungbogjegeo


duplicated()를 사용하면 중복된 행을 TRUE로, 아닌 행을 FALSE로 반환해 준다.


R 벡터 중복제거 - r begteo jungbogjegeo


진리값이 보기 어렵다면 which()안에 넣어 보자.


R 벡터 중복제거 - r begteo jungbogjegeo


3행과 6행이 TRUE, 중복이므로


다음과 같이 해당 행들을 출력하면 된다.


R 벡터 중복제거 - r begteo jungbogjegeo


물론 which()는 우리의 편의를 위해 넣은 것이므로


생략해도 결과는 동일하다.


FALSE인 행은 생략하고 TRUE인 행만 출력하게 된다.


R 벡터 중복제거 - r begteo jungbogjegeo

하지만 실제로 중복은 1행과 3행, 그리고 2행과 6행인데


1, 2행이 빠져 있어 잘 와닿지 않는다.


중복된 최초의 행까지 포함하려면


x[which(duplicated(x) | duplicated(x, fromLast=T) ),]


와 같이 duplicated()를 한 번 더 적용해 주면 된다.


R 벡터 중복제거 - r begteo jungbogjegeo


원리를 알아보자.


duplicated()의 [fromLast=] 옵션은 말 그대로 끝에서부터 중복 여부를 검사하라는 의미다.


즉 다음과 같은 x에서


R 벡터 중복제거 - r begteo jungbogjegeo


옵션 없는 duplicated()는 1행에서 아래로 내려가며 다음과 같이 동작한다.


R 벡터 중복제거 - r begteo jungbogjegeo


1행의 a1이 중복인가? FALSE


2행의 c3이 중복인가? FALSE


3행의 a1이 중복인가? TRUE


...



반면 [fromLast=T]의 옵션이 주어진 duplicated()는 7행에서 위로 올라오며 다음과 같이 동작한다.


R 벡터 중복제거 - r begteo jungbogjegeo


7행의 d4가 중복인가? FALSE <- 값 자체는 7번째에 쓰인다.


6행의 c3가 중복인가? FALSE <- 값은 6번째에 쓰인다.


...


2행의 c3가 중복인가? TRUE <- 값은 2번째에 쓰인다.


1행의 a1이 중복인가? TRUE <- 값은 1번째에 쓰인다.



그러므로 이 둘의 결과를 or("|")를 이용하여 합하면 중복된 행을 모두 볼 수 있다.


x[which( duplicated(x) | duplicated(x, fromLast=T) ) ,]


R 벡터 중복제거 - r begteo jungbogjegeo


행의 순서는 2016/09/26 - [R] - [R.아르] 원하는 순서로 데이터 정렬하기 order() 에서 나온


order() 를 이용하여 바꾸어도 되겠다.


R 벡터 중복제거 - r begteo jungbogjegeo


행이 셋 이상 다수 중복되어


중복된 회수를 파악하는 것이 중요하다면


plyr 라이브러리의 count()라는 함수를 사용하는 것이 유용하다.


R 벡터 중복제거 - r begteo jungbogjegeo


특정 열의 값만 파악할 수도 있다.


R 벡터 중복제거 - r begteo jungbogjegeo


중복된 행만 보려면 subset()을 이용하자.


R 벡터 중복제거 - r begteo jungbogjegeo






반응형

공유하기

게시글 관리

구독하기가벼운 블로그

'R' 카테고리의 다른 글

[R.아르] 찾아바꾸기 gsub()  (1)2016.09.26[R.아르] 원하는 순서로 데이터 정렬하기 order()  (0)2016.09.26[R.아르] R에서 피벗테이블 사용하기 dcast()  (2)2016.09.23[R. 아르] 리스트에 없는 항목만 추출하기 (차집합, setdiff())  (0)2016.09.23[R. 아르] 내용 합치기 paste()  (0)2016.09.22[R.아르] 중복된 값의 개수 세기(엑셀의 countif)  (1)2016.09.09[R.아르] R에서 엑셀의 vlookup() 기능 사용하기  (0)2016.09.08[R.아르] 특정 조건에 맞는 글자(이메일 주소)만 추출하기  (1)2016.09.06[R.아르] 특정 조건을 만족하는 행의 개수 구하기  (2)2016.09.05[R.아르] 특정 조건을 만족하는 행만 추출하기  (22)2016.09.05