22. JSON 파일 파싱
in Study on R Programming
Overview
R에서 JSON 파일을 파싱하여 R의 데이터 프레임으로 변경하는 방법을 알아본다.
예제 파일 : jsonexfile.zip
JSON
JSON(JavaScript Object Notation)은 속성-값 쌍(attribute–value pairs and array data types (or any other serializable value)) 또는 키-값 쌍으로 이루어진 데이터 오브젝트를 전달하기 위해 텍스트를 사용하는 개방형 표준 포맷이다.
주로 인터넷에서 자료를 주고 받을 때 그 자료를 표현하며, 자료의 종류에 큰 제한이 없고 프로그램의 변수 값을 표현하는데 적합하다.
JSON의 파일 확장자는 .json
이다.
JSON 파일의 구조
[
{
"name":"김철수",
"occupation":"개발자",
"information":
{
"address":"마포구 공덕동",
"info":
{
"height":180, "weight":75, "blood":"O"
}
}
},
{
"name":"박영희",
"occupation":"은행원",
"information":
{
"address":"용산구 도원동",
"info":
{
"height":165, "weight":48, "blood":"AB"
}
}
}
]
JSON 파일을 R으로 가져오기
JSON 파일을 R으로 가져오기 위해 jsonlite
패키지를 사용하며, fromJSON
함수를 이용하여 파일을 Dataframe 형식으로 가져올 수 있다.
예제를 통해 JSON의 데이터를 가져오는 방법을 알아본다.
예제 1
# install.packages('jsonlite')
library(jsonlite)
mJson <- 'R Basic Source/09.반정형/member.json'
mJson
# fromJSON 함수를 통해 JSON 파일 가져오기
mFrame <- fromJSON(mJson)
mFrame
summary(mFrame)
mode(mFrame)
class(mFrame)
# json 파일에서도 호출 가능
mFrame$name
mFrame$name[2]
# 중첩된 데이터 정보는 dot(.)로 연결하여 컬럼 이름을 만들어준다.
write.csv(mFrame, 'before.csv')
tot_df <- data.frame()
for (idx in 1:nrow(mFrame)) {
name <- mFrame$name[idx]
occupation <- mFrame$occupation[idx]
address <- mFrame$information$address[idx]
height <- mFrame$information$info$height[idx]
weight <- mFrame$information$info$weight[idx]
blood <- mFrame$information$info$blood[idx]
dFrame <- data.frame(name = name, occupation = occupation, address = address, height = height, weight = weight, blood = blood)
tot_df <- rbind(tot_df, dFrame)
}
tot_df
write.csv(tot_df, 'after.csv')
chart1 <- unlist(tot_df$height)
barplot(chart1, ylim = c(0, 200))
예제 2
library(jsonlite)
library(stringr)
par(family = 'D2Coding')
getColor <- function(x) {
return (rainbow(nrow(x)))
}
china_file <- '../R-Programming/R Basic Source/09.반정형/중국_방문객_정보.json'
china_visit <- fromJSON(china_file)
china_visit
newdata <- china_visit[c('yyyymm', 'visit_cnt')]
newdata$mm <- str_sub(newdata$yyyymm, 5, 6)
colnames(newdata) <- c('년월', '방문자수', '월')
newdata$월 <- str_c(newdata$월, '월')
xlabel <- newdata$월
# large number remove e+05
options(scipen = 1)
barplot(newdata$방문자수, col = getColor(newdata), names.arg = xlabel, ylim = c(0, 600000), ylab = 'Number of people')
newdata
예제 3
library(jsonlite)
library(stringr)
par(family = 'D2Coding')
getColor <- function(x) {
return (rainbow(nrow(x)))
}
mFile <- 'R Basic Source/09.반정형/somedata.json'
mFrame <- fromJSON(mFile)
mode(mFrame)
class(mFrame)
write.csv(mFrame, 'humans.csv', quote = F, row.names = F)
jsonData <- toJSON(mFrame)
jsonData
mode(jsonData)
class(jsonData)
예제 4
library(rJava)
library(KoNLP)
library(jsonlite)
library(stringr)
library(wordcloud2)
par(family = 'D2Coding')
getColor <- function(x) {
return (rainbow(nrow(x)))
}
fileName <- 'R Basic Source/09.반정형/김주혁_naver_news.json'
fullData <- fromJSON(fileName)
fullData
colnames(fullData)
desLen <- length(fullData$description)
newData <- c()
for(idx in 1:desLen) {
newData$desc <- c(newData, fullData$description[idx])
}
newData
# 명사 추출 함수
someData <- sapply(newData, extractNoun, USE.NAMES = F)
someData
mChkData <- unlist(someData)
mChkData
# 명사중 2글자 이상 6글자 이하 필터링
mChkData <- Filter(function(x) {
nchar(x) >= 2
}, mChkData)
mChkData <- Filter(function(x) {
nchar(x) <= 6
}, mChkData)
length(mChkData)
mChkData
res <- sort(table(mChkData), decreasing = T)
datalen <- 20 # 워드 클라우드의 개수
res <- head(res, datalen)
res
wordcloud2(res, size = 0.5, fontFamily = "D2Coding", color = "random-dark", shape = 'rectangle', shuffle = F, rotateRatio = 0.5, maxRotation = pi/4)
예제 5
library(rJava)
library(KoNLP)
library(jsonlite)
library(stringr)
library(dplyr)
library(reshape2)
library(devtools)
devtools::install_github("lchiffon/wordcloud2")
library(wordcloud2)
library(htmltools)
library(yaml)
library(base64enc)
library(htmlwidgets)
par(family = 'D2Coding')
getColor <- function(x) {
return (rainbow(nrow(x)))
}
#####################
fulldata <- fromJSON('jumsu.json')
fulldata
dlen <- length(fulldata$name)
dlen
res1 <- c()
for(idx in 1:dlen) {
res1$name <- c(res1$name, fulldata$name[idx])
res1$kor <- c(res1$kor, as.numeric(fulldata$kor[idx]))
res1$eng <- c(res1$eng, as.numeric(fulldata$eng[idx]))
res1$math <- c(res1$math, as.numeric(fulldata$math[idx]))
}
colnames(res1)
# jumsu.json 파일을 이용하여 학생들의 국영수 각각 평균 점수를 구하시오.
# 3 과목의 평균을 이용하여 Pie 그래프를 그리시오.
avg1 <- c()
avg1 <- c(avg1, round(mean(res1$kor), 2))
avg1 <- c(avg1, round(mean(res1$eng), 2))
avg1 <- c(avg1, round(mean(res1$math), 2))
avg1
colnames(res1[2:4])
pie(avg1, labels = colnames(res1[2:4]))
# 미국(275)_해외방문객정보(2016 ~ 2017).json 파일을 이용하여
# 매년(2016년과 2017년) 총 방문객 수를 이용하여 막대 그래프 그리기
usf <- fromJSON('미국(275)_해외방문객정보(2016 ~ 2017).json')
usf
summary(usf)
mData <- usf[c('yyyymm', 'visit_cnt')]
mData
mData$year <- as.numeric(str_sub(mData$yyyymm, 1, 4))
mData$month <- as.numeric(str_sub(mData$yyyymm, 5, 6))
mData
res2 <- mData[2:4]
res2 <- dcast(res2, month ~ year, value.var = 'visit_cnt')
res2
xlab1 <- res2[1]
res2 <- res2[2:3]
leg <- paste(t(xlab1[1]), '월')
par(cex = 0.7)
res2
barplot(as.matrix(res2), ylab = 'Visitor of U.S', beside = T, col = getColor(xlab1), legend = leg)
# 년도에 상관 없이 4분기의 총방문객을 이용하여 Pie 그래프를 그리시오.
mData
res3 <- c()
res3$cnt <- mData$visit_cnt
res3$month <- mData$month
res3 <- as.data.frame(res3)
res3
res3 <- res3 %>% group_by(month) %>% summarise(tot = sum(cnt))
q4 <- res3 %>% filter(month > 9)
res4 <- q4$tot
lbls <- c('10월', '11월', '12월')
lbls <- paste(lbls, '\n', res4)
pie(res4, labels = lbls, col = getColor(q4))
# pokedex-korean.json 파일을 이용하여
# name, img, type, height, weight 항목들만 추출하여 csv 파일로 저장하시오.
#
pok <- fromJSON('pokedex-korean.json')
pok
mode(pok)
class(pok)
nLen <- nrow(pok)
nLen
res5 <- data.frame()
for(idx in 1:nLen) {
name <- pok$name[idx]
img <- pok$img[idx]
type <- pok$type[idx]
height <- pok$height[idx]
weight <- pok$weight[idx]
tmp <- data.frame(name = name, img = img, type = type, height = height, weight = weight)
res5 <- rbind(res5, tmp)
}
res5
write.csv(res5, 'pokemon.csv', quote = F, row.names = F)
# 다음 url에 대하여 json을 읽어 들여서, node_id, name, full_name 3개의 컬럼만
# result.csv 파일에 저장해 보세요.
url = 'https://api.github.com/users/hadley/repos'
#
repos <- fromJSON(url)
nLen2 <- nrow(repos)
nLen2
res6 <- data.frame()
for(idx in 1:nLen2) {
node_id <- repos$node_id[idx]
name <- repos$name[idx]
full_name <- repos$full_name[idx]
tmp <- data.frame(node_id = node_id, name = name, full_name = full_name)
res6 <- rbind(res6, tmp)
}
res6
write.csv(res6, 'apiRes.csv', quote = F, row.names = F)
# jtbcnews_facebook_2016-10-01_2017-03-12.json 파일에서
# message 항목만 추출하여 워드 클라우드를 만들어 보세요.
#
news <- fromJSON('jtbcnews_facebook_2016-10-01_2017-03-12.json')
head(news)
summary(news)
colnames(news)
head(news$message)
newsLen <- length(news$message)
newsLen
msgData <- c()
for(idx in 1:newsLen) {
msgData <- c(msgData, news$message[idx])
}
head(msgData)
summary(msgData)
mode(msgData)
class(msgData)
nounData <- sapply(msgData, extractNoun, USE.NAMES = F)
nounData <- unlist(nounData)
nounData <- Filter(function(x) {
nchar(x) >= 2
}, nounData)
nounData <- Filter(function(x) {
nchar(x) <= 6
}, nounData)
length(nounData)
nounData
res7 <- sort(table(nounData), decreasing = T)
datalen <- 500
res7 <- head(res7, datalen)
res7
wordcloud2(res7, size = 1, fontFamily = "D2Coding", color = "random-dark", shape = 'rectangle', shuffle = F, rotateRatio = 0.5, maxRotation = pi/4,figPath = '../../R_data/191017/alice.png')