[SQL] 어떻게 R에서 SQL 순위 기능을 시뮬레이션?
SQL어떻게 R에서 SQL 순위 기능을 시뮬레이션?
참조 http://www.orafaq.com/node/, 무엇 오라클 ROW_NUMBER (), RANK (), 또는 DENSE_RANK () ( "순서에 따라 행에 할당 정수 값"과 같은 순위 기능의 R 동등한입니다 55)?
나는 각 기능의 기능은 잠재적으로 임시 방식으로 달성 할 수 있음을 동의합니다. 하지만 내 주요 관심사는 성능이다. 그것은 메모리와 속도를 위해 가입 또는 색인 액세스를 사용하지 않는 것이 좋은 것입니다.
해결법
-
==============================
1.data.table 패키지는, 특히 버전 1.8.1, 많은 SQL 측면에서 파티션의 기능의 제공으로 시작. R의 랭크 (X, ties.method = "분") 오라클 RANK ()와 유사하고, 모방 (후술) 요인 DENSE_RANK () 함수를 사용하는 방법이있다. 모방 ROW_NUMBER 할 수있는 방법은 말 명백해야한다.
data.table 패키지는, 특히 버전 1.8.1, 많은 SQL 측면에서 파티션의 기능의 제공으로 시작. R의 랭크 (X, ties.method = "분") 오라클 RANK ()와 유사하고, 모방 (후술) 요인 DENSE_RANK () 함수를 사용하는 방법이있다. 모방 ROW_NUMBER 할 수있는 방법은 말 명백해야한다.
다음은 그 예이다 : R-포지에서 data.table의 최신 버전을로드 :
install.packages("data.table", repos= c("http://R-Forge.R-project.org", getOption("repos"))) library(data.table)
몇 가지 예를 들어 데이터를 만들기 :
set.seed(10) DT<-data.table(ID=seq_len(4*3),group=rep(1:4,each=3),value=rnorm(4*3), info=c(sample(c("a","b"),4*2,replace=TRUE), sample(c("c","d"),4,replace=TRUE)),key="ID") > DT ID group value info 1: 1 1 0.01874617 a 2: 2 1 -0.18425254 b 3: 3 1 -1.37133055 b 4: 4 2 -0.59916772 a 5: 5 2 0.29454513 b 6: 6 2 0.38979430 a 7: 7 3 -1.20807618 b 8: 8 3 -0.36367602 a 9: 9 3 -1.62667268 c 10: 10 4 -0.25647839 d 11: 11 4 1.10177950 c 12: 12 4 0.75578151 d
순위 그룹 내에서 값을 감소시킴으로써, 각 ID합니다 (주의 - 값 앞의 순서 감소 나타내는데)
> DT[,valRank:=rank(-value),by="group"] ID group value info valRank 1: 1 1 0.01874617 a 1 2: 2 1 -0.18425254 b 2 3: 3 1 -1.37133055 b 3 4: 4 2 -0.59916772 a 3 5: 5 2 0.29454513 b 2 6: 6 2 0.38979430 a 1 7: 7 3 -1.20807618 b 2 8: 8 3 -0.36367602 a 1 9: 9 3 -1.62667268 c 3 10: 10 4 -0.25647839 d 3 11: 11 4 1.10177950 c 1 12: 12 4 0.75578151 d 2
위를 기록하였고, 가치 관계와 DENSE_RANK ()의 경우, 당신은 인자로 값을 변환 한 후 기본 정수 값을 반환 할 수 있습니다. 예를 들어, 그룹 내의 정보에 기초하여 각각의 ID 순위 (infoRankDense infoRank와 비교) :
DT[,infoRank:=rank(info,ties.method="min"),by="group"] DT[,infoRankDense:=as.integer(factor(info)),by="group"] R> DT ID group value info valRank infoRank infoRankDense 1: 1 1 0.01874617 a 1 1 1 2: 2 1 -0.18425254 b 2 2 2 3: 3 1 -1.37133055 b 3 2 2 4: 4 2 -0.59916772 a 3 1 1 5: 5 2 0.29454513 b 2 3 2 6: 6 2 0.38979430 a 1 1 1 7: 7 3 -1.20807618 b 2 2 2 8: 8 3 -0.36367602 a 1 1 1 9: 9 3 -1.62667268 c 3 3 3 10: 10 4 -0.25647839 d 3 2 2 11: 11 4 1.10177950 c 1 1 1 12: 12 4 0.75578151 d 2 2 2
추신. 안녕 매튜 Dowle.
LEAD 및 LAG
모방 LEAD 및 LAG를 들어, 여기에 제공된 답변을 시작합니다. 나는 그룹 내 ID의 순서에 따라 순위 변수를 만들 것입니다. 이는 상기와 가짜 데이터를 필요하지 않을 것입니다,하지만 ID를 그룹 내에서 순차적으로하지 않은 경우, 다음이 인생을 좀 더 어렵게 만들 것입니다. 그래서 여기에 비 순차적 ID를 가진 새로운 가짜 데이터입니다 :
set.seed(10) DT<-data.table(ID=sample(seq_len(4*3)),group=rep(1:4,each=3),value=rnorm(4*3), info=c(sample(c("a","b"),4*2,replace=TRUE), sample(c("c","d"),4,replace=TRUE)),key="ID") DT[,idRank:=rank(ID),by="group"] setkey(DT,group, idRank) > DT ID group value info idRank 1: 4 1 -0.36367602 b 1 2: 5 1 -1.62667268 b 2 3: 7 1 -1.20807618 b 3 4: 1 2 1.10177950 a 1 5: 2 2 0.75578151 a 2 6: 12 2 -0.25647839 b 3 7: 3 3 0.74139013 c 1 8: 6 3 0.98744470 b 2 9: 9 3 -0.23823356 a 3 10: 8 4 -0.19515038 c 1 11: 10 4 0.08934727 c 2 12: 11 4 -0.95494386 c 3
그런 다음, 이전 한 레코드의 값을 가져 그룹과 idRank 변수를 사용하고 idRank에서 1을 빼고 다 = '마지막'인수를 사용합니다. 두 항목 위의 기록에서 값을 얻으려면 2를 뺍니다.
DT[,prev:=DT[J(group,idRank-1), value, mult='last']] DT[,prev2:=DT[J(group,idRank-2), value, mult='last']] ID group value info idRank prev prev2 1: 4 1 -0.36367602 b 1 NA NA 2: 5 1 -1.62667268 b 2 -0.36367602 NA 3: 7 1 -1.20807618 b 3 -1.62667268 -0.3636760 4: 1 2 1.10177950 a 1 NA NA 5: 2 2 0.75578151 a 2 1.10177950 NA 6: 12 2 -0.25647839 b 3 0.75578151 1.1017795 7: 3 3 0.74139013 c 1 NA NA 8: 6 3 0.98744470 b 2 0.74139013 NA 9: 9 3 -0.23823356 a 3 0.98744470 0.7413901 10: 8 4 -0.19515038 c 1 NA NA 11: 10 4 0.08934727 c 2 -0.19515038 NA 12: 11 4 -0.95494386 c 3 0.08934727 -0.1951504
LEAD를 들어, '제'= 다중 행 idRank 변수와 스위치에 적절한 오프셋을 추가
DT[,nex:=DT[J(group,idRank+1), value, mult='first']] DT[,nex2:=DT[J(group,idRank+2), value, mult='first']] ID group value info idRank prev prev2 nex nex2 1: 4 1 -0.36367602 b 1 NA NA -1.62667268 -1.2080762 2: 5 1 -1.62667268 b 2 -0.36367602 NA -1.20807618 NA 3: 7 1 -1.20807618 b 3 -1.62667268 -0.3636760 NA NA 4: 1 2 1.10177950 a 1 NA NA 0.75578151 -0.2564784 5: 2 2 0.75578151 a 2 1.10177950 NA -0.25647839 NA 6: 12 2 -0.25647839 b 3 0.75578151 1.1017795 NA NA 7: 3 3 0.74139013 c 1 NA NA 0.98744470 -0.2382336 8: 6 3 0.98744470 b 2 0.74139013 NA -0.23823356 NA 9: 9 3 -0.23823356 a 3 0.98744470 0.7413901 NA NA 10: 8 4 -0.19515038 c 1 NA NA 0.08934727 -0.9549439 11: 10 4 0.08934727 c 2 -0.19515038 NA -0.95494386 NA 12: 11 4 -0.95494386 c 3 0.08934727 -0.1951504 NA NA
-
==============================
2.data.table v1.9.5의 +에서 구현되었습니다 (빠른 순위에 대한)) (프랭크 작동합니다. frankv로 (가)와 쉽게 프로그래밍 할 수 있습니다 어디 프랭크 () 대화 형 시나리오에서 유용합니다.
data.table v1.9.5의 +에서 구현되었습니다 (빠른 순위에 대한)) (프랭크 작동합니다. frankv로 (가)와 쉽게 프로그래밍 할 수 있습니다 어디 프랭크 () 대화 형 시나리오에서 유용합니다.
그것은 기본 :: 계급에서 사용할 수있는 모든 작업을 구현합니다. 또한, 장점은 다음과 같습니다
여기 @BenBarnes '(우수) 포스트에서 같은 data.table DT를 사용하여 위의 모든 점의 그림입니다.
require(data.table) set.seed(10) sample_n <- function(x, n) sample(x, n, replace=TRUE) DT <- data.table( ID = seq_len(4*3), group = rep(1:4,each=3), value = rnorm(4*3), info = c(sample_n(letters[1:2], 8), sample_n(letters[3:4], 4)))
또한, 최대 무작위, 평균 먼저 다른 방법의 분을 사용할 수 있습니다.
당신은 데이터의 하위 집합을 의미하고 그 그룹에 해당하는 데이터를 포함 .SD를 사용할 수 있습니다. .SD에 대한 자세한 내용은 data.table HTML 비네팅에 대한 소개를 참조하십시오.
당신은 유사 frankv 사용 COLS 인수와 열이 순서 인수를 사용하여 평가해야하는 순서에 열을 제공 할 수 있습니다.
기본 :: 순위와 비교하는 작은 벤치 마크 :
set.seed(45L) x = sample(1e4, 1e7, TRUE) system.time(ans1 <- base::rank(x, ties.method="first")) # user system elapsed # 22.200 0.255 22.536 system.time(ans2 <- frank(x, ties.method="first")) # user system elapsed # 0.745 0.014 0.762 identical(ans1, ans2) # [1] TRUE
-
==============================
3.나는 다음 사람만큼 data.table 좋아하지만 항상 필요는 없습니다. data.table 항상 빠른 수 있지만, 심지어 그룹의 수는 상당히 작은 경우 적당히 대용량 데이터 세트에 대한 plyr는 여전히 적절하게 수행합니다.
나는 다음 사람만큼 data.table 좋아하지만 항상 필요는 없습니다. data.table 항상 빠른 수 있지만, 심지어 그룹의 수는 상당히 작은 경우 적당히 대용량 데이터 세트에 대한 plyr는 여전히 적절하게 수행합니다.
무엇 벤 반스가 data.tables이 같은 컴팩트 단지 다 (그러나 나는 아마 느린 많은 경우에 이전에 언급 한 바와 같이) plyr를 사용 할 수 있습니다 사용했다 :
library(plyr) ddply(DT,.(group),transform,valRank = rank(-value)) ddply(DT,.(group),transform,valRank = rank(info,ties.method = "min"), valRankDense = as.integer(factor(info)))
심지어 모두에 하나의 추가 패키지를로드하지 않고 :
do.call(rbind,by(DT,DT$group,transform,valRank = rank(-value))) do.call(rbind,by(DT,DT$group,transform,valRank = rank(info,ties.method = "min"), valRankDense = as.integer(factor(info))))
당신이 비록 마지막 경우 구문 미묘한의 일부를 잃게됩니다.
-
==============================
4.나는 오라클의 분석 기능에 직접 해당하는이 있다고 생각하지 않습니다. Plyr 가능성이 있지만 모든 직접적 분석 기능의 일부를 달성 할 수있을 것입니다. 나는 R 별도로 각각의 기능을 복제 할 수 있습니다 확신하지만 난 모든 것을 할 것입니다 단일 패키지가 있다고 생각하지 않습니다.
나는 오라클의 분석 기능에 직접 해당하는이 있다고 생각하지 않습니다. Plyr 가능성이 있지만 모든 직접적 분석 기능의 일부를 달성 할 수있을 것입니다. 나는 R 별도로 각각의 기능을 복제 할 수 있습니다 확신하지만 난 모든 것을 할 것입니다 단일 패키지가 있다고 생각하지 않습니다.
당신이 R에 달성하는 데 필요한 특정 작업이 있다면, 다음 몇 가지 인터넷 검색을 수행하고 빈 올 경우에 StackOverflow 여기에 특정 질문을 부탁드립니다.
from https://stackoverflow.com/questions/11446254/how-to-emulate-sqls-rank-functions-in-r by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 는 SQL 업데이트 쿼리에서 집계 함수? (0) | 2020.06.02 |
---|---|
[SQL] 나는 오라클의 외래 키에 인덱스를 생성해야합니까? (0) | 2020.06.02 |
[SQL] ORA-01652 : 테이블 스페이스 시스템 128에 의해 임시 세그먼트를 확장 할 수 없습니다 : 어떻게 확장하려면? (0) | 2020.06.02 |
[SQL] 는 SQL Server 2008의 테이블에 Excel 스프레드 시트에서 데이터를 내보내는 방법 (0) | 2020.06.02 |
[SQL] SQLite는 :으로 선택? (0) | 2020.06.02 |