2014-11-26 7 views
3
data.table

는 R.은 조건부, 이름 목록이

열 A를 data.table 사용하여 중복 문제를 해결하기 위해 노력하고있다 사용하여 일부를 R의 열 B에 따라 열 A에 일치하는 행을 제거 그 중 여러 번 나타납니다. B 열은 날짜 목록입니다. 다른 컬럼들도 복사하고 싶습니다. (Date on Name에 일어난 일들)

그러나 나는 단지 1 개의 엔트리를 가진 새로운 datatable에서 각각의 사람들을위한 대부분의 활동만을보고 싶습니다. 가장 최근 날짜에 해당하는 각 이름에 대해

예 데이터

name.last  date 
1:  Adams 2014-10-20 
2:  Adams 2014-07-07 
3: Barnett 2014-11-06 
4: Barnett 2014-09-22 
5:  Bell 2014-10-22 
6:  Bell 2014-07-29 
7:  Burns 2014-09-08 
8:  Burns 2014-09-03 
9: Camacho 2014-08-12 
10: Camacho 2014-07-08 
11: Casillas 2014-10-07 
12: Casillas 2014-07-17 
13: Chavez 2014-09-23 
14: Chavez 2014-09-17 
15: Chavira 2014-07-15 
16: Chavira 2014-07-07 
17: Claren 2014-10-30 
18: Claren 2014-10-23 
19: Colleary 2014-11-11 
20: Colleary 2014-11-07 

대답은 내가있는 DT 키 setkey(dt,name.last)을 설정하지만 경우 (여기 이후 행이 각각의 제에 대한 가장 최근 날짜로 분류되어 있습니다.) 각 이름의 첫 번째 반환

unique()을 사용하여 중복을 제거하면 테이블의 순서가 변경됩니다 (이름의 알파벳순). unique(dt)을 사용하면 가장 최근 날짜 일 필요는없는 각 이름의 첫 번째 모양이 반환됩니다.

키를 두 열 이상으로 설정하면 setkeyv(dt,c(name.last,date)) 모든 키가 고유하므로 unique()을 사용하여 중복을 제거 할 수 없습니다.

문제는 여기에 게시 된 글 중 하나와 비슷합니다 : Collapsing data frame by selecting one row per group. 그러나 키를 설정 한 후에 내 데이터를 조작하여 데이터를 조작 할 수있는 방법을 제안 할 수 없다면 선택한 데이터가 첫 번째인지 마지막인지를 추측 할 수 없습니다.

답변

3

데이터 테이블을 주문하지 않고도이 작업을 수행 할 수있는 방법이 많이 있습니다. (duplicated은 매우 효율적이며 by도 사용하지 않으므로 주문하는 것이 좋습니다.)모든

첫째, 당신은 (비록 가장 효율적이지) date 물건을 쉽게

dt[, date := as.Date(date)] 

먼저 간단한 방법을 만들기 위해 클래스 Date의이 있는지 확인해야

dt[, max(date), name.last] 
#  name.last   V1 
# 1:  Adams 2014-10-20 
# 2: Barnett 2014-11-06 
# 3:  Bell 2014-10-22 
# 4:  Burns 2014-09-08 
# 5: Camacho 2014-08-12 
# 6: Casillas 2014-10-07 
# 7: Chavez 2014-09-23 
# 8: Chavira 2014-07-15 
# 9: Claren 2014-10-30 
# 10: Colleary 2014-11-11 

두 번째 (제공되는) 방법은 귀하의 것과 유사하지만 데이터 타일 setorder (data.table 버전> 1.9.4)을 사용하고 있으며 가장 효율적이어야합니다.

setorder(dt, name.last, -date)[!duplicated(name.last)] 
#  name.last  date 
# 1:  Adams 2014-10-20 
# 2: Barnett 2014-11-06 
# 3:  Bell 2014-10-22 
# 4:  Burns 2014-09-08 
# 5: Camacho 2014-08-12 
# 6: Casillas 2014-10-07 
# 7: Chavez 2014-09-23 
# 8: Chavira 2014-07-15 
# 9: Claren 2014-10-30 
# 10: Colleary 2014-11-11 

당신은 (너무 매우 효율적으로해야하는) data.tableunique 기능을 사용하고 (이미 그랬던 것처럼) setkeyduplicated에서 from.last = TRUE 지정하고 !

setkey(dt, name.last, date)[duplicated(name.last, from.last = TRUE)] 

#  name.last  date 
# 1:  Adams 2014-10-20 
# 2: Barnett 2014-11-06 
# 3:  Bell 2014-10-22 
# 4:  Burns 2014-09-08 
# 5: Camacho 2014-08-12 
# 6: Casillas 2014-10-07 
# 7: Chavez 2014-09-23 
# 8: Chavira 2014-07-15 
# 9: Claren 2014-10-30 
# 10: Colleary 2014-11-11 

세 번째 방법을 제거 ANS를 사용하여 동일한을 달성 할 수

unique(setorder(dt, name.last, -date), by = "name.last") 
#  name.last  date 
# 1:  Adams 2014-10-20 
# 2: Barnett 2014-11-06 
# 3:  Bell 2014-10-22 
# 4:  Burns 2014-09-08 
# 5: Camacho 2014-08-12 
# 6: Casillas 2014-10-07 
# 7: Chavez 2014-09-23 
# 8: Chavira 2014-07-15 
# 9: Claren 2014-10-30 
# 10: Colleary 2014-11-11 

마지막 메서드는 .SD입니다. 가장 효율적인 것은 아니지만 어떤 경우에는 모든 열을 반환하려는 경우 유용 할 수 있습니다. duplicated

setorder(dt, name.last, -date)[, .SD[1], name.last] 
#  name.last  date 
# 1:  Adams 2014-10-20 
# 2: Barnett 2014-11-06 
# 3:  Bell 2014-10-22 
# 4:  Burns 2014-09-08 
# 5: Camacho 2014-08-12 
# 6: Casillas 2014-10-07 
# 7: Chavez 2014-09-23 
# 8: Chavira 2014-07-15 
# 9: Claren 2014-10-30 
# 10: Colleary 2014-11-11 
1

이 글을 쓰면서 나는 알아 냈습니다. 후손 들어 ...

당신이 그룹에 처음으로 또는 마지막으로 원하는 날짜에 따라 수 있도록 이름과 날짜로 테이블을 주문하십시오. 예 : dt[order(names,-date)].

그리고 오히려 단순한, 키를 설정하고 unique()를 사용하는 것보다 : names가 복제 된 열입니다

dt[!duplicated(names)]

.

원하는 테이블을 출력해야합니다. 이것을하기위한보다 우아하고 믿을만한 방법이 있다면 나는 그것들을 듣는 것에 흥미가있을 것이다.

2

질문을 이해하고 있다면 sqldf 패키지를 사용하여보다 명확하게 처리 할 수 ​​있다고 생각합니다. 단점은 sql에 대해 알아야한다는 것입니다.

install.packages("sqldf") 
library("sqldf") 
dt <-data.frame(read.table(header = TRUE, text = " name.last  date 
1:  Adams 2014-10-20 
2:  Adams 2014-07-07 
3: Barnett 2014-11-06 
4: Barnett 2014-09-22 
5:  Bell 2014-10-22 
6:  Bell 2014-07-29 
7:  Burns 2014-09-08 
8:  Burns 2014-09-03 
9: Camacho 2014-08-12 
10: Camacho 2014-07-08 
11: Casillas 2014-10-07 
12: Casillas 2014-07-17 
13: Chavez 2014-09-23 
14: Chavez 2014-09-17 
15: Chavira 2014-07-15 
16: Chavira 2014-07-07 
17: Claren 2014-10-30 
18: Claren 2014-10-23 
19: Colleary 2014-11-11 
20: Colleary 2014-11-07") 
) 
head(dt) 
colnames(dt) <- c('names', 'date') 
sqldf("select names, min(date), max(date) from dt group by names") 

잘하면이 도움이되었습니다.

관련 문제