정렬, 순위, 순서 중 실무에서 가장 많이 하는 것이 정렬이다. R에서는 데이터의 성격을 미리 보자고 할 때, 사용을 한다. 주식의 시세의 차이를 계산 하다든지 증감율을 계산을 하고 싶다면 반드시 해야하는 것이 정렬이다.
house 데이터 셋은 아래 링크와 같이 있다.
https://drive.google.com/file/d/17bjJDtn8r8SazhUCE5N_WwKPZosuvm3m/view?usp=sharing
2.8.7 정렬, 순위, 순서
데이터 분석에 3가지 기능 (정렬하기, 순위, 순서 메기기)은 중요합니다. 예를 들어 순서 매기는 설명하면 다음과 같습니다.
houses <- read.table("houses.txt", header = T)
attach(houses)
names(houses)
## [1] "Location" "Price"
3개의 함수를 순위 벡터에 적용합니다.
ranks<-rank(Price)
sorted <- sort(Price)
orderd <- order(Price)
4개의 벡터를 이용해 데이터 프레임을 만들면 다음과 같습니다.
view<-data.frame(Price, ranks, sorted, orderd)
view
## Price ranks sorted orderd
## 1 325 12.0 95 9
## 2 201 10.0 101 6
## 3 157 5.0 117 10
## 4 162 6.0 121 12
## 5 164 7.0 157 3
## 6 101 2.0 162 4
## 7 211 11.0 164 5
## 8 188 8.5 188 8
## 9 95 1.0 188 11
## 10 117 3.0 201 2
## 11 188 8.5 211 7
## 12 121 4.0 325 1
순위
가격 자체는 특별한 순서로 되어 있지 않다. Price 데이터의 가장 작은 데이터의 ranks 값은 1이고 가장 높은 ranks 값은 length(Price)입니다. 첫 번째 요소 325의 가격은 Price에서 가장 높은 값이다. Price 벡터에서는 325보다 작은값이 11개가 있다는 것을 의미합니다. randk 값이 분수 값인 경우 같은 값이 존재하는것을 의미 합니다. Price에는 2개의 188이 있으며, 이값의 순위는 8.9가 됩니다. 두 값은 같기 때문에 ranks 값은 각 해당 순위의 평균인 (8+9)/2=8.5가 된다. 최저 가격은 96이고, ranks 값은 1이 된다.
정렬
정렬Sort 된 벡터는 매우 간단하다. 오름차순으로 정렬된 Price의 값을 내용으로 한다. 내림차순으로 정렬하고 싶다면, 다음과 같이 역순 함수 rev를 사용합니다.
y<- rev(sort(x))
예를 들어 반응 변수와 설명 변수의 값이 각기 다른 데이터 프레임에 1개의 데이터 프레임만을 대상으로 sort 함수를 사용하면 2개의 변수가 분리 되는 문제가 발생합니다. 게다가 unsort라는 함수는 존재하지 않기 때문에 x<-sort(x) 명령을 실행하는 것은 바람직 하지 않습니다.
순서
순서(Order)는 3가지 함수 중 가장 중요하지만 이해하기가 어렵습니다. 순서열에서 값은 1에서 12사이의 첨자입니다. 순서 함수는 입력값을 오름차순으로 정렬하는 순열을 내용으로 하는 정수 벡터를 계산합니다. 이러한 기능을 잘 알아둘 필요가 있다. Price의 가장 작은 값은 95입니다. 데이터 프레임보고 Price 벡터에서 몇 번째 값이 95인지 해당 첨자를 알아 봅니다. 열을 검색하면 행 번호가 9임을 알 수 있으며, 이 값이 orderd[1]이 됩니다. Price에서 두 번째 작은 값 101의 행 번호는 6이며 이 값이 ordered[2]가 됩니다. 세 번째 작은 값 Price(117)의 위는 10이며 이 값이 ordered[3]의 값 입니다.
따라서 이 함수는 데이터 프레임을 정렬하는 데 유용하게 사용합니다. 데이터를 정렬 하려면 sort보다는 위치첨자를 계산하는 계산하는 order 함수를 사용하는 것이 안전합니다. sort 함수에서 반응 변수와 설명 변수를 함께 사용하는 경우 모델링이 실행된 시점에서 실현 되지 않는 다면, 잠재적으로 좋지 않은 결과로 인하여 연결이 분리 될 수 있기 때문입니다. 가격 기준으로 정렬한 장소(Location)값을 얻기 위해 Location에 대한 첨자로 order(price)를 사용할 수 있습니다.
Location[order(Price)]
## [1] "Reading" "Staines" "Winkfield" "Newbury" "Bracknell"
## [6] "Camberley" "Bagshot" "Maidenhead" "Warfield" "Sunninghill"
## [11] "Windsor" "Ascot"
가격 기준으로 정렬한 장소(Location)값을 얻기 위해 Location에 대한 첨자로 order (price)를 사용 할 수 있습니다. 이러한 이유로 인하여 함수 내에서 order를 사용합니다.
Location[rev(order(Price))]
## [1] "Ascot" "Windsor" "Sunninghill" "Warfield" "Maidenhead"
## [6] "Bagshot" "Camberley" "Bracknell" "Newbury" "Winkfield"
## [11] "Staines" "Reading"
예제 1의 사전 준비 사항 2백만개의 데이터를 컨트롤 하므로 컴퓨터의 16GB의 메모리는 필수 이다.
예제 1
2019년 1월 부터 2022년 4월 까지 대한민국 실거래가 데이터 셋이 있다. 데이터는 2백만개 이고, 데이터 로딩 하는데, 1분 걸린다. 데이터셋에는 실거래가 정보가 있다. 아파트 가격이 높은순으로 정렬하여, 순위와 순서를 구하십시오.
library(httr)
library(readxl)
real_estate_fun <- function() {
# 2019년도 데이터 가져오기
url <-"https://drive.google.com/u/0/uc?id=1sTAf6f4SvMbBruZKf7jFCu0a5bdPkOc3&export=download"
GET(url, write_disk(tf <- tempfile(fileext = ".xlsx")))
apt_2019 <- read_excel(tf, 1L)
# 2020년도 데이터 가져오기
url <- "https://drive.google.com/u/0/uc?id=1QyP-Xi744CXvaTUV_6ep3pcMyY80a3Rv&export=download"
GET(url, write_disk(tf <- tempfile(fileext = ".xlsx")))
apt_2020 <- read_excel(tf, 1L)
# 2021년도 데이터 가져오기
url <- "https://drive.google.com/u/0/uc?id=15qs1ingQMZra-6w9_4adrwOPpm-H7WgC&export=download"
GET(url, write_disk(tf <- tempfile(fileext = ".xlsx")))
apt_2021 <- read_excel(tf, 1L)
# 2022년도 데이터 가져오기
url <- "https://drive.google.com/u/0/uc?id=1JC6JPtA4nK5ZRyii64NDO98LyU38kL0R&export=download"
GET(url, write_disk(tf <- tempfile(fileext = ".xlsx")))
apt_2022 <- read_excel(tf, 1L)
df <- rbind( apt_2019,
apt_2020,
apt_2021,
apt_2022)
return(df)
}
system.time(
df <- real_estate_fun()
)
## 사용자 시스템 elapsed
## 20.983 2.670 41.669
위와 같이 각 년도별로 하여, 구글 클라우드 시스템에서 데이터를 로딩 하였습니다.
이것보다 sapply
를 이용하면, 이것보다 간단하게 할 수 있으나, 가독성이 떨어져 그냥 하였습니다.
str(df)
## tibble [2,041,698 × 16] (S3: tbl_df/tbl/data.frame)
## $ 시군구 : chr [1:2041698] "강원도 강릉시 견소동" "강원도 강릉시 견소동" "강원도 강릉시 견소동" "강원도 강릉시 견소동" ...
## $ 번지 : chr [1:2041698] "202" "202" "202" "202" ...
## $ 본번 : chr [1:2041698] "0202" "0202" "0202" "0202" ...
## $ 부번 : chr [1:2041698] "0000" "0000" "0000" "0000" ...
## $ 단지명 : chr [1:2041698] "송정한신" "송정한신" "송정한신" "송정한신" ...
## $ 전용면적(㎡) : num [1:2041698] 39.1 59.8 59.8 43.4 39.1 ...
## $ 계약년월 : num [1:2041698] 201901 201901 201901 201901 201901 ...
## $ 계약일 : num [1:2041698] 3 4 4 8 17 21 29 29 31 7 ...
## $ 거래금액(만원): num [1:2041698] 9200 12000 12200 9500 9550 12000 13100 10900 9100 25000 ...
## $ 층 : num [1:2041698] 15 15 6 11 7 10 11 7 2 9 ...
## $ 건축년도 : num [1:2041698] 1997 1997 1997 1997 1997 ...
## $ 도로명 : chr [1:2041698] "경강로2539번길 8" "경강로2539번길 8" "경강로2539번길 8" "경강로2539번길 8" ...
## $ 해제사유발생일: num [1:2041698] NA NA NA NA NA NA NA NA NA NA ...
## $ 거래유형 : chr [1:2041698] "-" "-" "-" "-" ...
## $ 중개사소재지 : chr [1:2041698] "-" "-" "-" "-" ...
## $ 계약년도 : chr [1:2041698] "2019" "2019" "2019" "2019" ...
# 금액 역순으로 순위를 하기 위해 거래 금액 역순으로 처리
require(dplyr)
## 필요한 패키지를 로딩중입니다: dplyr
##
## 다음의 패키지를 부착합니다: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
# 거래금액 만원을 변경
df <- df %>% rename(거래금액_만원 = `거래금액(만원)`)
attach(df)
# 거래금액이 가장 큰 시군구 6개 표시 순서
head(시군구[rev(order(거래금액_만원))])
## [1] "서울특별시 용산구 한남동" "서울특별시 용산구 한남동"
## [3] "서울특별시 용산구 한남동" "서울특별시 강남구 청담동"
## [5] "서울특별시 강남구 청담동" "서울특별시 용산구 한남동"
head(단지명[rev(order(거래금액_만원))])
## [1] "파르크한남" "파르크한남" "파르크한남" "PH129" "PH129"
## [6] "파르크한남"
library(formattable)
trading <-거래금액_만원[rev(order(거래금액_만원))]
head(comma(trading, format = "d"))
## [1] 1,200,000 1,170,000 1,150,000 1,150,000 1,150,000 1,080,000
# 순위를 보기
ranks <- (length(trading) + 1) - rank(trading)
head(ranks)
## [1] 1 2 4 4 4 6
# 정렬 보기
sorted <- rev(sort(trading))
head(sorted)
## [1] 1200000 1170000 1150000 1150000 1150000 1080000
위의 내용을 정리하면, data.frame을 attach 한다음, order(순서), rank(순위), sort(정렬)을 한 것입니다.
댓글 없음:
댓글 쓰기