R의 data.table로
wrangling을 연습하고 101 exercises를 했다.
data.table은 용량이 큰 데이터를 다루는데 최적화되어 있다.
chain[
][
]이 된다는 게 특징이다. (3.5GB 데이터를 불러오는 데 10초 정도 걸리는 듯)
시원시원하게 나오니까 재미는 있는데 조금 헷갈려서 손에 붙기까지 연습을 해야할 것 같다.
사용해보기
1) install/import packages
install.packages("data.table")
library(data.table)
2) read in data using fread()
* data는 pisa.csv를 사용했으며 아래 링크에서 다운로드 가능하다.
4 Wrangling big data | Exploring, Visualizing, and Modeling Big Data with R
This book presents the materials for our NCME workshop on big data analysis in R.
okanbulut.github.io
pisa <- fread("pisa2015.csv", na.strings = "")
fread로 csv파일을 읽을 수 있다.
3) see the class the object / how big it is
class(pisa)
#data.table data.frame
print(object.size(pisa), unit = "GB")
##3.5GB
pisa 데이터의 class를 확인했고, 3.5GB라는 걸 알 수 있다.
4) 데이터 추출 및 csv 파일로 저장 (region6, random6)
region6 <- subset(pisa, CNT %in% c("United States", "Canada", "Mexico",
"B-S-J-G (China)", "Japan", "Korea",
"Germany", "Italy", "France", "Brazil",
"Colombia", "Uruguay", "Australia",
"New Zealand", "Jordan", "Israel", "Lebanon"))
#새로운 파일 만들기
fwrite(region6, file = "region6.csv")
random6 <- subset(pisa, CNT %in% c("Mexico", "Uruguay", "Japan",
"Germany", "New Zealand", "Lebanon"))
fwrite(random6, file = "random6.csv")
파일로 저장은 fwrite ! fread, fwrite이니 외우기에는 쉽다
5) Using the i in data.table
data.table의 기본 문법은
df[i, j, by] 이다.
그리고 기존 R에서처럼 pisa$CNTRYID <- 이렇게 열을 지정하지 않아도 된다.
pisa[CNTRYID ~] 이런식으로 쓰는 게 가능하다. (아래 코드 참고)
pisa[CNTRYID == "Mexico" & ST063Q01NA == "Checked"]
pisa
pisa[10:25]
나라가 mexico이고 st~코드에 "checked"라고 답한 사람들의 데이터.
chain 을 활용하는 것도 가능하다.
pisa[CNTRYID == "Mexico" & ST063Q01NA == "Checked"
][17:20]
head(pisa$CNTRYID)
pisa[order(CNTRYID, decreasing = TRUE)
][,
head(CNTRYID)]
head도 쓸 수 있다.
아래 코드의 결과는
> pisa[order(CNTRYID, decreasing = TRUE)
+ ][,
+ head(CNTRYID)]
[1] "Vietnam" "Vietnam" "Vietnam" "Vietnam" "Vietnam" "Vietnam"
나라명으로 내림차순 한 후에, (chain) head를 이용해서 맨 앞 6개 나라명 출력
**연습 문제
1. Subset all the Female students (ST004D01T) in Germany
pisa[CNTRYID == "Germany" & ST004D01T == "Female"]
2. How many female students are there in Germany?
pisa[CNTRYID == "Germany" & ST004D01T == "Female"
][,
table(CNTRYID)]
##3197명
5) Using the n in data.table
pisa[, list(CNTRYID)]
pisa[, .(CNTRYID)]
> pisa[, list(CNTRYID)]
CNTRYID
1: Albania
2: Albania
3: Albania
4: Albania
5: Albania
---
519330: Argentina (Ciudad Aut처noma de Buenos)
519331: Argentina (Ciudad Aut처noma de Buenos)
519332: Argentina (Ciudad Aut처noma de Buenos)
519333: Argentina (Ciudad Aut처noma de Buenos)
두 개 코드 결과는 같다.
6) 원하는 정보를 알고자 할 때
#JAPAN과 MEXICO학생 중 체육을 수강한 수를 알고 싶을 때
pisa[CNTRYID %in% c("Mexico", "Japan"),
table(ST063Q01NA)]
#checked 4283 not checked 9762
#"i get very tense when i study for a test"라고 답한 수
pisa[CNTRYID %in% c("Mexico", "Japan"),
table(ST119Q04NA)]
pisa[CNTRYID %in% c("Mexico", "Japan"),
.(tense = factor(ST118Q04NA, levels = c("Strongly disagree", "Disagree", "Agree", "Strongly agree")))
][,
table(tense)
]
table을 chain으로 사용하면 간단히 확인이 가능하다.
> pisa[CNTRYID %in% c("Mexico", "Japan"),
+ .(tense = factor(ST118Q04NA, levels = c("Strongly disagree", "Disagree", "Agree", "Strongly agree")))
+ ][,
+ table(tense)
+ ]
tense
Strongly disagree Disagree Agree
2904 5313 4074
Strongly agree
1760
7) 요약 통계 & plot
pisa[CNTRYID %in% c("Mexico", "Japan"),
.(xbar = mean(SCIEEFF, na.rm = T),
sigma = sd(SCIEEFF, na.rm = T),
minimum = min(SCIEEFF, na.rm = T),
med = median(SCIEEFF, na.rm = T),
maximum = max(SCIEEFF, na.rm = T))]
### xbar sigma minimum med maximum
###1: -0.08693672 1.216052 -3.7565 -0.0541 3.2775
sd, mean, minimum, median 등 요약 통계량을 확인할 수 있다. (위 코드에서는 mexico와 japan을 묶어서 연산했다.)
pisa[CNTRYID %in% c("Mexico", "Japan"),
.(plot(y = SCIEEFF, x = JOYSCIE,
col = rgb(red = 0, green = 0, blue = 0, alpha = 0.3)),
xbar.joyscie = mean(JOYSCIE, na.rm = T))]
8) eat.dinner(ST078Q01NA) 변수 변환
#After leaving school did you : Eat dinner
table(pisa$ST078Q01NA)
#created a new variable(:= 가 새 변수를 만들어줌)
pisa[,
"eat.dinner" := sapply(ST078Q01NA,
function(x) {
if (is.na(x)) NA
else if (x == "No") 0L
else if (x == "Yes") 1L
})
][,
table(eat.dinner)]
방과후에 저녁 먹는다고 답한 사람을 TABLE로 확인하고,
기존 변수를 식별하기 쉬운 eat.dinner 변수를 추가하여 값도 0, 1로 변환해줬다.
> table(pisa$ST078Q01NA)
No Yes
23617 373131
eat.dinner
0 1
23617 373131
NO -> 0 , Yes - > 1 로 변환됐다.
이외에 답변이 Yes, no인 다른 변수들에 대해서도 변환을 진행한다.
9) 변수 변환
bin.to.num <- function(x){
if (is.na(x)) NA
else if (x == "Yes") 1L
else if (x == "No") 0L
}
#전부 0, 1 로 변환해서 알아볼 수 있는 변수로 변환함 (yes/no나오는 답을)
pisa[, `:=`
(female = ifelse(ST004D01T == "Female", 1, 0),
sex = ST004D01T,
# At my house we have ...
desk = sapply(ST011Q01TA, bin.to.num),
own.room = sapply(ST011Q02TA, bin.to.num),
quiet.study = sapply(ST011Q03TA, bin.to.num),
computer = sapply(ST011Q04TA, bin.to.num),
software = sapply(ST011Q05TA, bin.to.num),
internet = sapply(ST011Q06TA, bin.to.num),
lit = sapply(ST011Q07TA, bin.to.num),
poetry = sapply(ST011Q08TA, bin.to.num),
art = sapply(ST011Q09TA, bin.to.num),
book.sch = sapply(ST011Q10TA, bin.to.num),
tech.book = sapply(ST011Q11TA, bin.to.num),
dict = sapply(ST011Q12TA, bin.to.num),
art.book = sapply(ST011Q16NA, bin.to.num))]
yes를 1, no를 0으로 변환하는 사용자 정의 함수를 만들어 적용했다.
** 연습 문제
- The computer and software variables that were created above ask a student whether they had a computer in their home that they can use for school work (computer) and whether they had educational software in their home (software). Find the proportion of students in the Germany and Uruguay that have a computer in their home or have educational software.
pisa[CNTRYID %in% c("Germany", "Uruguay"),
.(computer = mean(computer, na.rm = TRUE),
software = mean(software, na.rm = TRUE)),
by = .(country = CNTRYID)]
10) using 'by' in data.tabel (groupby)
#집에 자신의 방이 있는 각 국가의 학생 비율
pisa[,
.(mean(own.room, na.rm = TRUE)),
by = .(CNTRYID)
][1:6,
]
#캐나다와 아이슬란드에서, 성별에 따라 시집을 가지고 있는 비율과
#과학에 즐거움을 느끼는 비율 비교
pisa[CNTRYID %in% c("Canada", "Iceland"),
.(poetry = mean(poetry, na.rm = TRUE),
enjoy = mean(JOYSCIE, na.rm = TRUE)),
by = .(country = CNTRYID, sex = sex)]
country sex poetry enjoy
1: Canada Female 0.3632105 0.29635781
2: Canada Male 0.3123878 0.40950018
3: Iceland Female 0.7280806 0.03583745
4: Iceland Male 0.7011494 0.30316273
11) sorting
#내림차순(국가별)
pisa[,
.(poetry = mean(poetry, na.rm = TRUE)),
by = .(country = CNTRYID)
][order(poetry, decreasing = TRUE)
][1:6
]
country poetry
1: Kosovo 0.8352507
2: Russian Federation 0.8045568
3: Romania 0.8019434
4: Georgia 0.7495615
5: B-S-J-G (China) 0.7442052
6: Estonia 0.7422718
국가별 시집을 갖고 있는 비율을 구하여 결과를 내림차순했다.
12) fit a regression model
get.params <- function(cntry){
mod <- lm(SCIEEFF ~ JOYSCIE + sex, cntry)
est.params <- list(int = coef(mod)[[1]], enjoy.slope = coef(mod)[[2]], sex.slope = coef(mod)[[3]])
return(est.params)
}
g7.params <- pisa[CNTRYID %in% c("Canada", "France", "Germany", "Italy",
"Japan", "United Kingdom", "United States"),
get.params(.SD),
by = .(CNTRYID)]
g7.params
CNTRYID int enjoy.slope sex.slope
1: Canada 0.009803357 0.4370945 0.21489577
2: France -0.208698984 0.4760903 0.17743126
3: Germany -0.019150031 0.4316565 0.17971821
4: Italy -0.030880063 0.3309990 0.18831666
5: Japan -0.353806055 0.3914385 0.04912039
6: United Kingdom 0.009711647 0.5182592 0.18981965
7: United States 0.096920721 0.3907848 0.15022008
과학 효능감에 따른 학생들의 과학 점수를 예측하기 위한 회귀모델을 만들었고, 성별과 효능감에 따른 결과를 g7 나라에 따라 출력했다. 다중 회귀 분석 모델도 학습시킬 수 있으며, 결과는 intercept(int) 와 slope로 출력된다.
**연습 문제
- Calculate the proportion of students who have art in their home (art) and the average age (AGE) of the students by gender.
pisa[,
.(art = mean(art, na.rm = TRUE),
age = mean(AGE, na.rm = TRUE)),
by = .(sex = sex)]
13) melting data
#학생 아이디 -> ID, 재택변수 하위 설정
pisa$id <- 1:nrow(pisa)
athome <- subset(pisa, select = c(id, desk:art.book))
athome.l <- melt(athome,
id.vars = "id",
measure.vars = c("desk", "own.room", "quiet.study", "lit",
"poetry", "art", "book.sch", "tech.book",
"dict", "art.book"))
athome.l
#형식 추측
athome.guess <- melt(athome)
athome.guess
#잘못함. id가 문자형 벡터로 설정되었다면 올바르게 추측했을 테지만
#변수의 이름을 추측하도록 허용해서는 안 됨.
#와이드 형식으로 돌아가기
athome.w <- dcast(athome.l,
id ~ variable)
athome.w
14) using sparklyr
#sparklyr
library("sparklyr")
library("dplyr")
sc <- spark_connect(master = "local")
#데이터 하위 집합 설정
pisa_sub <- subset(pisa, CNTRYID %in% c("Canada", "France", "Germany",
"Italy", "Japan", "United Kingdom",
"United States"),
select = c("DISCLISCI", "TEACHSUP", "IBTEACH", "TDTEACH",
"ENVAWARE", "JOYSCIE", "INTBRSCI", "INSTSCIE",
"SCIEEFF", "EPIST", "SCIEACT", "BSMJ", "MISCED",
"FISCED", "OUTHOURS", "SMINS", "TMINS",
"BELONG", "ANXTEST", "MOTIVAT", "COOPERATE",
"PERFEED", "unfairteacher", "HEDRES", "HOMEPOS",
"ICTRES", "WEALTH", "ESCS", "math", "reading",
"CNTRYID", "sex"))
#데이터 복사
pisa_tbl <- copy_to(sc, pisa_sub, overwrite = TRUE)
#독일 데이터 중 여학생만 보기
pisa_tbl %>%
filter(CNTRYID == "Germany" & sex == "Female")
#과학 수업의 평균 징계 분위기를 국가 및 성별로 계산,
#성별이 아닌 국가별로 순서 변경
pisa_tbl %>%
group_by(CNTRYID, sex) %>%
summarize(ave_disclip = mean(DISCLISCI, na.rm = TRUE)) %>%
arrange(CNTRYID, sex)
#함수를 새용한 새 변수 추가(가정 교육 자원, 가정 소유물)
pisa_tbl %>%
mutate(totl_home = HEDRES + HOMEPOS) %>%
group_by(CNTRYID) %>%
summarize(xbar = mean(totl_home, na.rm = TRUE))
참고 링크
빠른 처리를 지원하는 r의 data.table패키지
data.table: Extension of `data.frame` (r-project.org)
101 R data.table Exercises - Machine Learning Plus
101 R data.table Exercises - Machine Learning Plus
The data.table package in R is super fast when it comes to handling data. It has a syntax that reduces keystrokes while making R code easier to read. These set of exercises are designed to help you to oil your data brain through solving data manipulation e
www.machinelearningplus.com
-> 연습 문제
'R > 개념 공부' 카테고리의 다른 글
[R] R/R studio 설치하기 (0) | 2022.11.09 |
---|
댓글