Ver3.0 ๐ R ์ธ์ด์ ํต๊ณ ๋ถ์: ๋ฐ์ดํฐ ์ฌ์ด์ธ์ค๋ฅผ ์ํ ์ ๋ฌธ ๋๊ตฌ ์๋ฒฝ ๊ฐ์ด๋

๐ R ์ธ์ด์ ํต๊ณ ๋ถ์: ๋ฐ์ดํฐ ์ฌ์ด์ธ์ค๋ฅผ ์ํ ์ ๋ฌธ ๋๊ตฌ ์๋ฒฝ ๊ฐ์ด๋
ํต๊ณํ์๋ค์ด ์ฌ๋ํ๋ ๊ทธ ์ธ์ด, R์ ๋ชจ๋ ๊ฒ์ ํํค์ณ๋ณด์! ๐
R์ 1993๋ ๋ด์ง๋๋ ์คํด๋๋ ๋ํ์ ๋ก์ค ์ดํ์นด(Ross Ihaka)์ ๋ก๋ฒํธ ์ ํ๋งจ(Robert Gentleman)์ด ๊ฐ๋ฐํ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ๋๋ค. ์ด๋ฆ๋ ์ฌ๋ฐ์ฃ ? ๋ ๊ฐ๋ฐ์์ ์ด๋ฆ์ด ๋ชจ๋ 'R'๋ก ์์ํด์ R์ด๋ผ๊ณ ์ง์๋ค๋ ์ค์ด ์์ด์. ๐ค
ํ์ง๋ง R์ ์ง์ง ๋งค๋ ฅ์ ์ด๋ฆ์ด ์๋๋ผ **ํต๊ณ ๋ถ์์ ํนํ๋ DNA**์ ์์ต๋๋ค. ๋ค๋ฅธ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ค์ด ๋ฒ์ฉ์ ์ธ ๋ชฉ์ ์ผ๋ก ์ค๊ณ๋ ๋ฐ๋ฉด, R์ ์ฒ์๋ถํฐ ํต๊ณํ์๋ค์ ์ํด, ํต๊ณํ์๋ค์ ์ํด ๋ง๋ค์ด์ก๊ฑฐ๋ ์.
R์ ์ฌ์ฉํ๋ฉด ๋ณต์กํ ํต๊ณ ๋ถ์์ด ๋ง์น ๋ ๊ณ ๋ธ๋ก ์กฐ๋ฆฝํ๋ฏ ์ฌ์์ง๋๋ค. ์ ํ ํ๊ท, ๋ก์ง์คํฑ ํ๊ท, ์๊ณ์ด ๋ถ์, ๋ฒ ์ด์ง์ ํต๊ณ, ์์กด ๋ถ์... ์ด๋ฆ๋ง ๋ค์ด๋ ์ด์ง๋ฌ์ด ์ด๋ฐ ๋ถ์๋ค์ด R์์๋ ๋ช ์ค์ ์ฝ๋๋ก ๋๋ฑ ํด๊ฒฐ๋ฉ๋๋ค.
# ์ ํ ํ๊ท ๋ถ์ ์์ - ์ ๋ง ์ด๊ฒ ๋์
๋๋ค!
model <- lm(price ~ area + rooms, data = housing_data)
summary(model)
# ๊ฒฐ๊ณผ ์๊ฐํ๋ ํ ์ค์ด๋ฉด OK
plot(model)
์ ์ฝ๋๋ฅผ ๋ณด์ธ์. ์ฃผํ ๊ฐ๊ฒฉ์ ๋ฉด์ ๊ณผ ๋ฐฉ ๊ฐ์๋ก ์์ธกํ๋ ํ๊ท ๋ชจ๋ธ์ ๋ง๋ค๊ณ , ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ๊ณ , ์๊ฐํ๊น์ง ํ๋๋ฐ ๊ณ ์ 3์ค์ด๋ฉด ์ถฉ๋ถํฉ๋๋ค. ๋ค๋ฅธ ์ธ์ด์๋ค๋ฉด? ์ต์ 20~30์ค์ ๊ฐ์คํด์ผ ํ์ ๊ฑฐ์์. ๐
๋ฐ์ดํฐ ์๊ฐํ์์ R์ ggplot2 ํจํค์ง๋ ๊ทธ์ผ๋ง๋ก **์ ์ค**์ ๋๋ค. "Grammar of Graphics"๋ผ๋ ์ฒ ํ์ ๊ธฐ๋ฐ์ผ๋ก ์ค๊ณ๋์ด, ๋ง์น ๋ฌธ์ฅ์ ๋ง๋ค๋ฏ์ด ๊ทธ๋ํ๋ฅผ ๋ง๋ค ์ ์์ด์.
# ggplot2๋ก ๋ฉ์ง ๊ทธ๋ํ ๋ง๋ค๊ธฐ
library(ggplot2)
ggplot(data = sales_data, aes(x = date, y = revenue, color = region)) +
geom_line(size = 1.2) +
geom_point(size = 3) +
theme_minimal() +
labs(title = "์ง์ญ๋ณ ๋งค์ถ ์ถ์ด",
x = "๋ ์ง",
y = "๋งค์ถ์ก (๋ฐฑ๋ง์)") +
scale_color_brewer(palette = "Set2")
์ด ์ฝ๋๋ ์ง์ญ๋ณ ๋งค์ถ ์ถ์ด๋ฅผ ๋ณด์ฌ์ฃผ๋ ์ธํฐ๋ํฐ๋ธํ ๊ทธ๋ํ๋ฅผ ๋ง๋ญ๋๋ค. ์ ๊ทธ๋ํ์ ์ ์ ์ถ๊ฐํ๊ณ , ๊น๋ํ ํ ๋ง๋ฅผ ์ ์ฉํ๊ณ , ์ ๋ชฉ๊ณผ ์ถ ๋ ์ด๋ธ์ ๋ฌ๊ณ , ์์ ํ๋ ํธ๊น์ง ์ง์ ํ๋๋ฐ ๋จ ๋ช ์ค์ด๋ฉด ์ถฉ๋ถํ์ฃ . ๐
๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ๋ ๋ฐ์ดํฐ ์ฌ์ด์ธ์ค ์์ ์ 80%๋ฅผ ์ฐจ์งํ๋ค๋ ๋ง, ๋ค์ด๋ณด์ จ๋์? R์ tidyverse ์ํ๊ณ, ํนํ dplyr ํจํค์ง๋ ์ด ์ง๋ฃจํ ์์ ์ ์ฆ๊ฑฐ์ด ๊ฒฝํ์ผ๋ก ๋ฐ๊ฟ์ค๋๋ค. ๐
library(dplyr)
# ํ์ดํ ์ฐ์ฐ์(%>%)๋ก ๋ฐ์ดํฐ ์ฒ๋ฆฌ ํ๋ฆ์ ์ง๊ด์ ์ผ๋ก!
result <- customer_data %>%
filter(age >= 20 & age <= 40) %>%
group_by(region) %>%
summarise(
avg_purchase = mean(purchase_amount),
total_customers = n()
) %>%
arrange(desc(avg_purchase))
# 20~40์ธ ๊ณ ๊ฐ์ ์ง์ญ๋ณ๋ก ๊ทธ๋ฃนํํ๊ณ
# ํ๊ท ๊ตฌ๋งค์ก๊ณผ ๊ณ ๊ฐ ์๋ฅผ ๊ณ์ฐํ ํ
# ํ๊ท ๊ตฌ๋งค์ก ๊ธฐ์ค์ผ๋ก ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ
์ด ์ฝ๋์ ์๋ฆ๋ค์์ด ๋ณด์ด์๋์? ๋ง์น ์์ด ๋ฌธ์ฅ์ ์ฝ๋ฏ์ด ์ฝ๋๋ฅผ ์ฝ์ ์ ์์ต๋๋ค. "๊ณ ๊ฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์์ โ 20~40์ธ๋ฅผ ํํฐ๋งํ๊ณ โ ์ง์ญ๋ณ๋ก ๊ทธ๋ฃนํํ ๋ค์ โ ํ๊ท ๊ณผ ๊ฐ์๋ฅผ ๊ณ์ฐํ๊ณ โ ์ ๋ ฌํด๋ผ" ์ด๋ ๊ฒ์!
R์ ๋จ์ํ ๊ธฐ์ ํต๊ณ๋ฅผ ๋์ด ์ต์ฒจ๋จ ํต๊ณ ๊ธฐ๋ฒ๋ค์ ์ง์ํฉ๋๋ค. ์ผ๋ฐํ ์ ํ ๋ชจ๋ธ(GLM), ํผํฉ ํจ๊ณผ ๋ชจ๋ธ(Mixed Effects Models), ๊ตฌ์กฐ ๋ฐฉ์ ์ ๋ชจ๋ธ๋ง(SEM), ๋ฒ ์ด์ง์ ์ถ๋ก ... ์ด๋ฐ ๊ณ ๊ธ ๊ธฐ๋ฒ๋ค์ด R์์๋ ํ์ค ๊ธฐ๋ฅ์ฒ๋ผ ์ ๊ณต๋ฉ๋๋ค.
| ๋ถ์ ์ ํ | ์ฃผ์ ํจํค์ง | ํ์ฉ ๋ถ์ผ |
|---|---|---|
| ์๊ณ์ด ๋ถ์ | forecast, tseries | ์ฃผ๊ฐ ์์ธก, ์์ ์์ธก |
| ์์กด ๋ถ์ | survival, survminer | ์ํ ์ฐ๊ตฌ, ๊ณ ๊ฐ ์ดํ ๋ถ์ |
| ํ ์คํธ ๋ง์ด๋ | tm, tidytext | ๊ฐ์ฑ ๋ถ์, ํ ํฝ ๋ชจ๋ธ๋ง |
| ๊ณต๊ฐ ๋ถ์ | sf, sp, leaflet | ์ง๋ฆฌ ์ ๋ณด ์์คํ , ๋ถ๋์ฐ ๋ถ์ |
| ๋คํธ์ํฌ ๋ถ์ | igraph, network | ์์ ๋คํธ์ํฌ, ์กฐ์ง ๋ถ์ |
"R์ ํต๊ณ๋ง ์ํ๋ ๊ฑฐ ์๋์ผ?"๋ผ๊ณ ์๊ฐํ์ จ๋ค๋ฉด ์ค์ฐ์ ๋๋ค! R์ ๋จธ์ ๋ฌ๋๊ณผ ๋ฅ๋ฌ๋ ๋ถ์ผ์์๋ ๊ฐ๋ ฅํ ๋๊ตฌ๋ค์ ์ ๊ณตํฉ๋๋ค.
# caret ํจํค์ง๋ก ๋จธ์ ๋ฌ๋ ๋ชจ๋ธ ํ์ต
library(caret)
# ๋ฐ์ดํฐ ๋ถํ
set.seed(123)
trainIndex <- createDataPartition(iris$Species, p = 0.8, list = FALSE)
trainData <- iris[trainIndex, ]
testData <- iris[-trainIndex, ]
# ๋๋ค ํฌ๋ ์คํธ ๋ชจ๋ธ ํ์ต
model <- train(Species ~ .,
data = trainData,
method = "rf",
trControl = trainControl(method = "cv", number = 10))
# ์์ธก ๋ฐ ํ๊ฐ
predictions <- predict(model, testData)
confusionMatrix(predictions, testData$Species)
caret ํจํค์ง๋ 200๊ฐ ์ด์์ ๋จธ์ ๋ฌ๋ ์๊ณ ๋ฆฌ์ฆ์ ํต์ผ๋ ์ธํฐํ์ด์ค๋ก ์ ๊ณตํฉ๋๋ค. ์๊ณ ๋ฆฌ์ฆ์ ๋ฐ๊พธ๊ณ ์ถ์ผ๋ฉด? method ํ๋ผ๋ฏธํฐ๋ง ๋ณ๊ฒฝํ๋ฉด ๋ฉ๋๋ค. "rf"๋ฅผ "xgbTree"๋ก ๋ฐ๊พธ๋ฉด ๋๋ค ํฌ๋ ์คํธ๊ฐ XGBoost๋ก ๋ฐ๋๋ ๊ฑฐ์ฃ ! ๐ฏ
R Shiny๋ R ์ฝ๋๋ง์ผ๋ก ์ธํฐ๋ํฐ๋ธํ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ค ์ ์๊ฒ ํด์ฃผ๋ ํ๋ ์์ํฌ์ ๋๋ค. HTML, CSS, JavaScript๋ฅผ ๋ชฐ๋ผ๋ ๊ด์ฐฎ์์! ๐
library(shiny)
ui <- fluidPage(
titlePanel("์ค์๊ฐ ๋ฐ์ดํฐ ๋์๋ณด๋"),
sidebarLayout(
sidebarPanel(
selectInput("variable", "๋ณ์ ์ ํ:",
choices = c("๋งค์ถ", "๋ฐฉ๋ฌธ์", "์ ํ์จ")),
dateRangeInput("dates", "๊ธฐ๊ฐ ์ ํ:")
),
mainPanel(
plotOutput("trendPlot"),
tableOutput("summaryTable")
)
)
)
server <- function(input, output) {
output$trendPlot <- renderPlot({
# ์ ํ๋ ๋ณ์์ ๊ธฐ๊ฐ์ ๋ฐ๋ฅธ ๊ทธ๋ํ ์์ฑ
# ์ค์ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ก์ง
})
output$summaryTable <- renderTable({
# ์์ฝ ํต๊ณ ํ
์ด๋ธ ์์ฑ
})
}
shinyApp(ui = ui, server = server)
์ด ์ฝ๋๋ก ๋ง๋ ๋์๋ณด๋๋ ์ฌ์ฉ์๊ฐ ๋ณ์์ ๊ธฐ๊ฐ์ ์ ํํ๋ฉด ์ค์๊ฐ์ผ๋ก ๊ทธ๋ํ์ ํ ์ด๋ธ์ด ์ ๋ฐ์ดํธ๋ฉ๋๋ค. ์น ๊ฐ๋ฐ ์ง์ ์์ด๋ ์ ๋ฌธ์ ์ธ ๋ฐ์ดํฐ ๋์๋ณด๋๋ฅผ ๋ง๋ค ์ ์๋ค๋, ์ ๋ง ๋๋์ง ์๋์? ๐
ํ ์ํ์ ๋ฐ์ดํฐ ๋ถ์ํ์ด ๋์ถ ์ฐ์ฒด ์ํ์ ์์ธกํ๋ ๋ชจ๋ธ์ ๊ฐ๋ฐํ์ต๋๋ค. R์ ๊ฐ๋ ฅํ ํต๊ณ ๊ธฐ๋ฅ์ ํ์ฉํด ๊ณ ๊ฐ์ ์ ์ฉ ์ ์, ์๋, ๋์ถ ์ด๋ ฅ ๋ฑ์ ๋ถ์ํ์ฃ .
# ๋ก์ง์คํฑ ํ๊ท๋ก ์ฐ์ฒด ํ๋ฅ ์์ธก
library(pROC)
# ๋ชจ๋ธ ํ์ต
default_model <- glm(default ~ credit_score + income + loan_amount +
employment_years + debt_ratio,
data = loan_data,
family = binomial)
# ROC ๊ณก์ ์ผ๋ก ๋ชจ๋ธ ์ฑ๋ฅ ํ๊ฐ
roc_curve <- roc(loan_data$default,
predict(default_model, type = "response"))
auc(roc_curve) # AUC ์ ์ ํ์ธ
# ๋ณ์ ์ค์๋ ํ์ธ
summary(default_model)
๊ฒฐ๊ณผ๋? ๋ชจ๋ธ์ AUC๊ฐ 0.85๋ฅผ ๋์ด ์ฐ์ํ ์์ธก ์ฑ๋ฅ์ ๋ณด์๊ณ , ์ํ์ ์ด๋ฅผ ํตํด ๋์ถ ์ฌ์ฌ ํ๋ก์ธ์ค๋ฅผ ๊ฐ์ ํ ์ ์์์ต๋๋ค. ์ฐ์ฒด์จ์ด 15% ๊ฐ์ํ๋ค๊ณ ํ๋ค์! ๐ฐ
ํ ์ ์์ ํ ์ ์กฐ์ฌ๋ R์ ์ฌ์ฉํด ์์ฐ ๋ผ์ธ์ ๋ถ๋๋ฅ ์ ๋ถ์ํ๊ณ ์์ธกํ์ต๋๋ค. ํต๊ณ์ ๊ณต์ ๊ด๋ฆฌ(SPC)๋ฅผ R๋ก ๊ตฌํํ ๊ฑฐ์ฃ .
library(qcc)
# ๊ด๋ฆฌ๋ ์์ฑ
quality_control <- qcc(defects_data,
type = "xbar",
title = "์์ฐ ๋ผ์ธ ํ์ง ๊ด๋ฆฌ๋")
# ๊ณต์ ๋ฅ๋ ฅ ๋ถ์
process_capability <- process.capability(quality_control,
spec.limits = c(LSL, USL))
# ์ด์ ํจํด ๊ฐ์ง
violations <- qcc.violations(quality_control)
์ด ์์คํ ์ ๋์ ํ ํ ๋ถ๋ํ ๋ฐ์๋ฅ ์ด 30% ๊ฐ์ํ๊ณ , ์กฐ๊ธฐ ๊ฒฝ๋ณด ์์คํ ์ผ๋ก ๋๊ท๋ชจ ๋ถ๋ ๋ฐ์์ ์ฌ์ ์ ๋ฐฉ์งํ ์ ์์์ต๋๋ค. ๐ฏ
ํ ์ด์ปค๋จธ์ค ํ์ฌ๋ R์ ํ์ฉํด ๊ณ ๊ฐ ์ธ๊ทธ๋จผํ ์ด์ ๊ณผ ๊ฐ์ธํ๋ ๋ง์ผํ ์ ๋ต์ ์๋ฆฝํ์ต๋๋ค.
library(cluster)
library(factoextra)
# K-means ํด๋ฌ์คํฐ๋ง์ผ๋ก ๊ณ ๊ฐ ์ธ๋ถํ
customer_segments <- kmeans(customer_features, centers = 5)
# ์ต์ ํด๋ฌ์คํฐ ์ ๊ฒฐ์
fviz_nbclust(customer_features, kmeans, method = "wss")
# ํด๋ฌ์คํฐ ์๊ฐํ
fviz_cluster(customer_segments, data = customer_features,
palette = "jco",
ggtheme = theme_minimal())
# ๊ฐ ์ธ๊ทธ๋จผํธ๋ณ ํน์ฑ ๋ถ์
segment_profiles <- customer_data %>%
mutate(segment = customer_segments$cluster) %>%
group_by(segment) %>%
summarise(
avg_purchase = mean(purchase_amount),
avg_frequency = mean(purchase_frequency),
avg_recency = mean(days_since_last_purchase)
)
๊ฒฐ๊ณผ์ ์ผ๋ก 5๊ฐ์ ๋ช ํํ ๊ณ ๊ฐ ์ธ๊ทธ๋จผํธ๋ฅผ ๋ฐ๊ฒฌํ๊ณ , ๊ฐ ์ธ๊ทธ๋จผํธ์ ๋ง์ถคํ ๋ง์ผํ ๋ฉ์์ง๋ฅผ ์ ๋ฌํด ์ ํ์จ์ 40% ํฅ์์์ผฐ์ต๋๋ค! ๐
R์ ์ฒ์ ์์ํ๋ค๋ฉด ์ด๋ฐ ์์๋ก ํ์ตํ๋ ๊ฒ์ ์ถ์ฒํฉ๋๋ค:
**1๋จ๊ณ: R ๊ธฐ๋ณธ ๋ฌธ๋ฒ** - ๋ณ์, ๋ฐ์ดํฐ ํ์ , ๋ฒกํฐ, ๋ฆฌ์คํธ - ์กฐ๊ฑด๋ฌธ, ๋ฐ๋ณต๋ฌธ, ํจ์ ์์ฑ - ๋ฐ์ดํฐ ํ๋ ์ ๋ค๋ฃจ๊ธฐ# R ๊ธฐ์ด ์์
# ๋ฒกํฐ ์์ฑ
numbers <- c(1, 2, 3, 4, 5)
names <- c("Alice", "Bob", "Charlie")
# ๋ฐ์ดํฐ ํ๋ ์ ์์ฑ
df <- data.frame(
name = names,
age = c(25, 30, 35),
salary = c(50000, 60000, 70000)
)
# ํจ์ ์์ฑ
calculate_bonus <- function(salary, rate = 0.1) {
return(salary * rate)
}
# ์ ์ฉ
df$bonus <- calculate_bonus(df$salary)
๊ธฐ์ด๋ฅผ ๋ค์ก๋ค๋ฉด ์ด์ ์ค์ ๊ธฐ์ ์ ์ตํ ์ฐจ๋ก์ ๋๋ค:
**1๋จ๊ณ: tidyverse ๋ง์คํฐํ๊ธฐ** - dplyr๋ก ๋ฐ์ดํฐ ์กฐ์ - tidyr๋ก ๋ฐ์ดํฐ ์ ๋ฆฌ - purrr๋ก ํจ์ํ ํ๋ก๊ทธ๋๋ฐlibrary(tidyverse)
# tidyverse ์คํ์ผ์ ๋ฐ์ดํฐ ๋ถ์
analysis_result <- sales_data %>%
# ๊ฒฐ์ธก์น ์ ๊ฑฐ
drop_na() %>%
# ๋ ์ง ํ์ ๋ณํ
mutate(date = as.Date(date)) %>%
# ์๋ณ ์ง๊ณ
group_by(month = floor_date(date, "month")) %>%
summarise(
total_sales = sum(amount),
avg_sales = mean(amount),
transaction_count = n()
) %>%
# ์ ์ ๋๋น ์ฆ๊ฐ๋ฅ ๊ณ์ฐ
mutate(
growth_rate = (total_sales - lag(total_sales)) / lag(total_sales) * 100
)
์ด์ R์ ๊ณ ๊ธ ๊ธฐ๋ฅ๋ค์ ๋ง์คํฐํ ์๊ฐ์ ๋๋ค:
**1๋จ๊ณ: ๊ณ ๊ธ ํ๋ก๊ทธ๋๋ฐ** - R ํจํค์ง ๊ฐ๋ฐ - ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ (S3, S4, R6) - C++์ R ์ฐ๋ (Rcpp) - ๋ณ๋ ฌ ์ฒ๋ฆฌ์ ์ฑ๋ฅ ์ต์ ํ **2๋จ๊ณ: ํนํ ๋ถ์ผ ์ ๋ฌธ์ฑ** - ๋ฒ ์ด์ง์ ํต๊ณ (Stan, JAGS) - ๋ฅ๋ฌ๋ (keras, tensorflow) - ๋น ๋ฐ์ดํฐ ์ฒ๋ฆฌ (sparklyr, data.table) - ๊ณต๊ฐ ๋ฐ์ดํฐ ๋ถ์ (sf, sp) **3๋จ๊ณ: ํ๋ก๋์ ํ๊ฒฝ** - Shiny ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ๋ฐ - R Markdown์ผ๋ก ๋ณด๊ณ ์ ์๋ํ - API ๊ฐ๋ฐ (plumber) - Docker๋ฅผ ํ์ฉํ ๋ฐฐํฌR์ ์ง์ ํ ํ์ ๋ฐฉ๋ํ ํจํค์ง ์ํ๊ณ์ ์์ต๋๋ค. 18,000๊ฐ๊ฐ ๋๋ ํจํค์ง ์ค์์ ๊ผญ ์์์ผ ํ ๊ฒ๋ค์ ์๊ฐํฉ๋๋ค:
library(dplyr)
# filter, select, mutate, summarise, arrange ๋ฑ์ ์ง๊ด์ ์ธ ํจ์๋ค
data %>% filter(age > 30) %>% select(name, salary) %>% arrange(desc(salary))
ggplot(data, aes(x = x_var, y = y_var)) +
geom_point(aes(color = category), size = 3) +
geom_smooth(method = "lm") +
theme_minimal() +
labs(title = "Beautiful Visualization")
library(shiny)
# ์ธํฐ๋ํฐ๋ธ ๋์๋ณด๋๋ฅผ R ์ฝ๋๋ง์ผ๋ก!
shinyApp(ui = ui, server = server)
# CRAN์์ ์ค์น
install.packages("ํจํค์ง๋ช
")
# GitHub์์ ์ต์ ๊ฐ๋ฐ ๋ฒ์ ์ค์น
devtools::install_github("์ฌ์ฉ์๋ช
/ํจํค์ง๋ช
")
# ์ฌ๋ฌ ํจํค์ง ํ๋ฒ์ ์ค์น
install.packages(c("dplyr", "ggplot2", "tidyr"))
๋ฐ์ดํฐ ์ฌ์ด์ธ์ค ์ปค๋ฎค๋ํฐ์์ ์์ํ ๋ ผ์๊ฑฐ๋ฆฌ์ฃ . "R์ด ๋์? Python์ด ๋์?" ํ์ง๋ง ์ ๋ต์ "์ํฉ์ ๋ฐ๋ผ ๋ค๋ฅด๋ค"์ ๋๋ค. ๊ฐ๊ฐ์ ๊ฐ์ ์ ์๊ณ ์ ์ฌ์ ์์ ์ฌ์ฉํ๋ ๊ฒ์ด ํ๋ช ํฉ๋๋ค. ๐ค
๋ณต์กํ ํต๊ณ ๋ชจ๋ธ๋ง, ๊ฐ์ค ๊ฒ์ , ๋ฒ ์ด์ง์ ๋ถ์ ๋ฑ์ด ํ์ํ๋ค๋ฉด R์ด ์๋์ ์ผ๋ก ์ ๋ฆฌํฉ๋๋ค. ํต๊ณํ์๋ค์ด ๋ง๋ ์ต์ ํต๊ณ ๊ธฐ๋ฒ๋ค์ด R ํจํค์ง๋ก ๊ฐ์ฅ ๋จผ์ ์ถ์๋๊ฑฐ๋ ์.
**2. ๋ฐ์ดํฐ ์๊ฐํ๊ฐ ์ค์ํ ๋**ggplot2์ ์๊ฐํ ํ์ง์ Python์ matplotlib์ด๋ seaborn์ ๋ฅ๊ฐํฉ๋๋ค. ํนํ ์ถํ ํ์ง์ ๊ทธ๋ํ๊ฐ ํ์ํ ํ์ ์ฐ๊ตฌ๋ ๋ณด๊ณ ์ ์์ฑ์ ์ต์ ์ ๋๋ค.
**3. ๋น ๋ฅธ ํ๋กํ ํ์ดํ์ด ํ์ํ ๋**R์ ๊ฐ๊ฒฐํ ๋ฌธ๋ฒ๊ณผ ํ๋ถํ ํจํค์ง ๋๋ถ์ ์์ด๋์ด๋ฅผ ๋น ๋ฅด๊ฒ ๊ตฌํํ๊ณ ํ ์คํธํ ์ ์์ต๋๋ค.
**4. ๋น์ฆ๋์ค ๋ถ์๊ฐ๋ ํต๊ณํ์๊ฐ ์ฃผ ์ฌ์ฉ์์ผ ๋**ํ๋ก๊ทธ๋๋ฐ ๋ฐฐ๊ฒฝ์ด ์ฝํ ๋๋ฉ์ธ ์ ๋ฌธ๊ฐ๋ค๋ R์ ์๋์ ์ผ๋ก ์ฝ๊ฒ ๋ฐฐ์ธ ์ ์์ต๋๋ค.
TensorFlow, PyTorch ๋ฑ ๋ฅ๋ฌ๋ ํ๋ ์์ํฌ๋ Python์ด 1์์์ ๋๋ค. R์์๋ ์ฌ์ฉ ๊ฐ๋ฅํ์ง๋ง Python์ด ๋ ์์ฐ์ค๋ฝ์ฃ .
**2. ํ๋ก๋์ ๋ฐฐํฌ๊ฐ ์ค์ํ ๋**์น ์๋น์ค, API, ์๋ํ ์คํฌ๋ฆฝํธ ๋ฑ ์ํํธ์จ์ด ์์ง๋์ด๋ง ์ธก๋ฉด์์๋ Python์ด ๋ ๊ฐ๋ ฅํฉ๋๋ค.
**3. ๋ฒ์ฉ ํ๋ก๊ทธ๋๋ฐ์ด ํ์ํ ๋**๋ฐ์ดํฐ ๋ถ์ ์ธ์๋ ์น ํฌ๋กค๋ง, ์๋ํ, ์์คํ ๊ด๋ฆฌ ๋ฑ ๋ค์ํ ์์ ์ ํด์ผ ํ๋ค๋ฉด Python์ด ์ ํฉํฉ๋๋ค.
**4. ๋๊ท๋ชจ ํ ํ์ ํ๊ฒฝ์ผ ๋**์ํํธ์จ์ด ๊ฐ๋ฐ ํ์ค๊ณผ ๋๊ตฌ๋ค์ด Python ์ํ๊ณ์ ๋ ์ ๊ฐ์ถฐ์ ธ ์์ต๋๋ค.
| ๋น๊ต ํญ๋ชฉ | R | Python |
|---|---|---|
| ํ์ต ๊ณก์ | ํต๊ณ ๋ฐฐ๊ฒฝ์ด ์๋ค๋ฉด ์ฌ์ | ํ๋ก๊ทธ๋๋ฐ ๋ฐฐ๊ฒฝ์ด ์๋ค๋ฉด ์ฌ์ |
| ํต๊ณ ๋ถ์ | โญโญโญโญโญ | โญโญโญโญ |
| ๋จธ์ ๋ฌ๋ | โญโญโญโญ | โญโญโญโญโญ |
| ๋ฅ๋ฌ๋ | โญโญโญ | โญโญโญโญโญ |
| ์๊ฐํ | โญโญโญโญโญ | โญโญโญโญ |
| ํ๋ก๋์ ๋ฐฐํฌ | โญโญโญ | โญโญโญโญโญ |
| ์ปค๋ฎค๋ํฐ | ํต๊ณ/ํ๊ณ ์ค์ฌ | ์ฐ์ ๊ณ ์ค์ฌ |
| ์๋ | โญโญโญ | โญโญโญโญ |
๋ฐ์ดํฐ ์๊ฐํ๋ R์ ๊ฐ์ฅ ํฐ ๊ฐ์ ์ค ํ๋์ ๋๋ค. ์ฝ๋ ๋ช ์ค๋ก ์ ๋ฌธ๊ฐ ์์ค์ ๊ทธ๋ํ๋ฅผ ๋ง๋ค ์ ์์ฃ . ์ค์ ์์ ์์ฃผ ์ฌ์ฉ๋๋ ์๊ฐํ ์์ ๋ค์ ์ดํด๋ณผ๊น์? ๐จ
library(ggplot2)
library(lubridate)
library(scales)
# ์ฃผ๊ฐ ๋ฐ์ดํฐ ์๊ฐํ
stock_plot <- ggplot(stock_data, aes(x = date, y = price)) +
# ์์ญ ๊ทธ๋ํ๋ก ์ถ์ธ ํํ
geom_area(fill = "#667eea", alpha = 0.3) +
# ์ ๊ทธ๋ํ ์ถ๊ฐ
geom_line(color = "#667eea", size = 1.2) +
# ์ด๋ํ๊ท ์ ์ถ๊ฐ
geom_line(aes(y = ma_20), color = "#f5576c",
linetype = "dashed", size = 1) +
# ์ถ ํฌ๋งทํ
scale_x_date(date_breaks = "1 month", date_labels = "%Y-%m") +
scale_y_continuous(labels = comma) +
# ํ
๋ง์ ๋ ์ด๋ธ
theme_minimal() +
theme(
plot.title = element_text(size = 16, face = "bold"),
axis.text.x = element_text(angle = 45, hjust = 1)
) +
labs(
title = "์ฃผ๊ฐ ์ถ์ด ๋ฐ 20์ผ ์ด๋ํ๊ท ",
x = "๋ ์ง",
y = "์ฃผ๊ฐ (์)",
caption = "๋ฐ์ดํฐ ์ถ์ฒ: ํ๊ตญ๊ฑฐ๋์"
)
print(stock_plot)
# ๋ฒ๋ธ ์ฐจํธ๋ก 3๊ฐ ๋ณ์ ๋์ ํํ
bubble_plot <- ggplot(country_data,
aes(x = gdp_per_capita,
y = life_expectancy,
size = population,
color = continent)) +
geom_point(alpha = 0.7) +
# ํฌ๊ธฐ ๋ฒ์ ์กฐ์
scale_size(range = c(2, 20),
labels = comma,
name = "์ธ๊ตฌ") +
# ์์ ํ๋ ํธ
scale_color_brewer(palette = "Set2", name = "๋๋ฅ") +
# ๋ก๊ทธ ์ค์ผ์ผ ์ ์ฉ
scale_x_log10(labels = comma) +
# ํ
๋ง
theme_minimal() +
theme(legend.position = "right") +
labs(
title = "๊ตญ๊ฐ๋ณ GDP, ๊ธฐ๋์๋ช
, ์ธ๊ตฌ ๊ด๊ณ",
x = "1์ธ๋น GDP (USD, ๋ก๊ทธ ์ค์ผ์ผ)",
y = "๊ธฐ๋์๋ช
(์ธ)"
)
# ์ธํฐ๋ํฐ๋ธํ๊ฒ ๋ง๋ค๊ธฐ
library(plotly)
ggplotly(bubble_plot)
library(reshape2)
# ์๊ด๊ณ์ ํ๋ ฌ ๊ณ์ฐ
cor_matrix <- cor(numeric_data)
# ํํธ๋งต์ฉ ๋ฐ์ดํฐ ๋ณํ
cor_melted <- melt(cor_matrix)
# ํํธ๋งต ์์ฑ
heatmap_plot <- ggplot(cor_melted, aes(Var1, Var2, fill = value)) +
geom_tile(color = "white") +
# ์๊ด๊ณ์ ๊ฐ ํ์
geom_text(aes(label = round(value, 2)),
color = "black", size = 3) +
# ์์ ๊ทธ๋ผ๋์ธํธ
scale_fill_gradient2(
low = "#2196f3",
mid = "white",
high = "#f44336",
midpoint = 0,
limit = c(-1, 1),
name = "์๊ด๊ณ์"
) +
theme_minimal() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
axis.title = element_blank()
) +
labs(title = "๋ณ์ ๊ฐ ์๊ด๊ด๊ณ ํํธ๋งต") +
coord_fixed()
print(heatmap_plot)
# ๊ทธ๋ฃน๋ณ ๋ถํฌ ๋น๊ต
distribution_plot <- ggplot(sales_data,
aes(x = region, y = revenue, fill = region)) +
# ๋ฐ์ด์ฌ๋ฆฐ ํ๋กฏ์ผ๋ก ๋ถํฌ ํํ ํํ
geom_violin(alpha = 0.5, trim = FALSE) +
# ๋ฐ์คํ๋กฏ์ผ๋ก ์ฌ๋ถ์์ ํ์
geom_boxplot(width = 0.2, alpha = 0.8) +
# ๊ฐ๋ณ ๋ฐ์ดํฐ ํฌ์ธํธ ์ถ๊ฐ
geom_jitter(width = 0.1, alpha = 0.3, size = 1) +
# ์์
scale_fill_brewer(palette = "Pastel1") +
# ํ
๋ง
theme_minimal() +
theme(legend.position = "none") +
labs(
title = "์ง์ญ๋ณ ๋งค์ถ ๋ถํฌ ๋น๊ต",
x = "์ง์ญ",
y = "๋งค์ถ์ก (๋ฐฑ๋ง์)"
) +
# ํ๊ท ์ ์ถ๊ฐ
stat_summary(fun = mean, geom = "point",
shape = 23, size = 3, fill = "red")
print(distribution_plot)
# ์ฌ๋ฌ ์นดํ
๊ณ ๋ฆฌ๋ฅผ ํ ๋ฒ์ ๋น๊ต
facet_plot <- ggplot(time_series_data,
aes(x = date, y = value, color = metric)) +
geom_line(size = 1) +
# ๋ฉํธ๋ฆญ๋ณ๋ก ํจ๋ ๋ถํ
facet_wrap(~ metric, scales = "free_y", ncol = 2) +
# ์์
scale_color_viridis_d() +
# ํ
๋ง
theme_minimal() +
theme(
legend.position = "none",
strip.text = element_text(face = "bold", size = 12)
) +
labs(
title = "์ฃผ์ ์งํ ์ถ์ด",
x = "๋ ์ง",
y = "๊ฐ"
)
print(facet_plot)
2. ๋ฐ์ดํฐ-์ํฌ ๋น์จ: ๋ถํ์ํ ๊ฒฉ์์ , ํ ๋๋ฆฌ, ๋ฐฐ๊ฒฝ์ ์ ๊ฑฐํด ๋ฐ์ดํฐ ์์ฒด์ ์ง์คํ๊ฒ ๋ง๋์ธ์.
3. ์ผ๊ด์ฑ: ๊ฐ์ ๋ณด๊ณ ์ ๋ด์์๋ ์์, ํฐํธ, ์คํ์ผ์ ์ผ๊ด๋๊ฒ ์ ์งํ์ธ์.
4. ์ ๊ทผ์ฑ: ์์๋ง์ผ๋ก ์ ๋ณด๋ฅผ ์ ๋ฌํ์ง ๋ง๊ณ ๋ชจ์, ํจํด, ๋ ์ด๋ธ๋ ํจ๊ป ์ฌ์ฉํ์ธ์.
R์ด ๋๋ฆฌ๋ค๋ ํธ๊ฒฌ์ด ์์ง๋ง, ์ฌ๋ฐ๋ฅธ ๊ธฐ๋ฒ์ ์ฌ์ฉํ๋ฉด ๋๋ผ์ธ ์ ๋๋ก ๋น ๋ฅธ ์ฑ๋ฅ์ ๋ผ ์ ์์ต๋๋ค. ์ค์ ์ต์ ํ ํ๋ค์ ๊ณต์ ํฉ๋๋ค! โก
# โ ๋๋ฆฐ ๋ฐฉ๋ฒ: ๋ฐ๋ณต๋ฌธ ์ฌ์ฉ
slow_sum <- function(x) {
result <- 0
for(i in 1:length(x)) {
result <- result + x[i]
}
return(result)
}
# โ
๋น ๋ฅธ ๋ฐฉ๋ฒ: ๋ฒกํฐํ ์ฐ์ฐ
fast_sum <- function(x) {
return(sum(x))
}
# ์ฑ๋ฅ ๋น๊ต
library(microbenchmark)
x <- 1:1000000
microbenchmark(
slow = slow_sum(x),
fast = fast_sum(x),
times = 10
)
# fast๊ฐ 100๋ฐฐ ์ด์ ๋น ๋ฆ
๋๋ค!
# โ ๋๋ฆฐ ๋ฐฉ๋ฒ
df$new_col <- apply(df, 1, function(row) {
row['col1'] + row['col2']
})
# โ
๋น ๋ฅธ ๋ฐฉ๋ฒ
df$new_col <- df$col1 + df$col2
# ์กฐ๊ฑด๋ถ ์ฐ์ฐ๋ ๋ฒกํฐํ
# โ ๋๋ฆฐ ๋ฐฉ๋ฒ
df$category <- apply(df, 1, function(row) {
if(row['value'] > 100) "High" else "Low"
})
# โ
๋น ๋ฅธ ๋ฐฉ๋ฒ
df$category <- ifelse(df$value > 100, "High", "Low")
# ๋๋ dplyr::case_when ์ฌ์ฉ
df$category <- case_when(
df$value > 100 ~ "High",
df$value > 50 ~ "Medium",
TRUE ~ "Low"
)
library(data.table)
# ๋ฐ์ดํฐ ํ๋ ์์ data.table๋ก ๋ณํ
dt <- as.data.table(large_df)
# ๋น ๋ฅธ ๊ทธ๋ฃน ์ฐ์ฐ
result <- dt[, .(
avg_value = mean(value),
total = sum(amount),
count = .N
), by = .(category, region)]
# ํค ์ค์ ์ผ๋ก ๋ ๋น ๋ฅธ ์กฐ์ธ
setkey(dt1, id)
setkey(dt2, id)
merged <- dt1[dt2] # ๋งค์ฐ ๋น ๋ฅธ ์กฐ์ธ
# ์ฐธ์กฐ ์
๋ฐ์ดํธ (๋ฉ๋ชจ๋ฆฌ ํจ์จ์ )
dt[, new_col := value * 2] # ๋ณต์ฌ ์์ด ์ง์ ์์
library(parallel)
library(foreach)
library(doParallel)
# ์ฝ์ด ์ ํ์ธ
num_cores <- detectCores() - 1 # ํ๋๋ ์์คํ
์ฉ์ผ๋ก ๋จ๊น
# ํด๋ฌ์คํฐ ์์ฑ
cl <- makeCluster(num_cores)
registerDoParallel(cl)
# ๋ณ๋ ฌ ์ฒ๋ฆฌ
results <- foreach(i = 1:1000, .combine = rbind) %dopar% {
# ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฌ๋ ์์
complex_calculation(i)
}
# ํด๋ฌ์คํฐ ์ข
๋ฃ
stopCluster(cl)
# ๊ฐ๋จํ ๋ณ๋ ฌ lapply
results <- mclapply(data_list, function(x) {
process_data(x)
}, mc.cores = num_cores)
# ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ํ์ธ
object.size(large_object)
format(object.size(large_object), units = "MB")
# ๋ถํ์ํ ๊ฐ์ฒด ์ ๊ฑฐ
rm(temp_data)
gc() # ๊ฐ๋น์ง ์ปฌ๋ ์
๊ฐ์ ์คํ
# ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ ์ธ ๋ฐ์ดํฐ ์ฝ๊ธฐ
library(data.table)
# ํ์ํ ์ปฌ๋ผ๋ง ์ฝ๊ธฐ
dt <- fread("large_file.csv",
select = c("col1", "col2", "col3"))
# ์ฒญํฌ ๋จ์๋ก ์ฒ๋ฆฌ
library(readr)
f <- function(x, pos) {
# ๊ฐ ์ฒญํฌ ์ฒ๋ฆฌ
process_chunk(x)
}
read_csv_chunked("huge_file.csv",
callback = DataFrameCallback$new(f),
chunk_size = 10000)
library(Rcpp)
# C++ ํจ์ ์ ์
cppFunction('
NumericVector fast_cumsum(NumericVector x) {
int n = x.size();
NumericVector result(n);
result[0] = x[0];
for(int i = 1; i < n; i++) {
result[i] = result[i-1] + x[i];
}
return result;
}
')
# R์์ ํธ์ถ
x <- 1:1000000
result <- fast_cumsum(x)
# ๋ด์ฅ ํจ์์ ๋น๊ตํด๋ ๋น์ทํ๊ฑฐ๋ ๋ ๋น ๋ฆ!
2. ํ๋กํ์ผ๋ง ํ์: Rprof()๋ profvis ํจํค์ง๋ก ์ด๋ ๋ถ๋ถ์ด ๋๋ฆฐ์ง ์ ํํ ํ์ ํ์ธ์.
3. ๊ฐ๋ ์ฑ vs ์ฑ๋ฅ: ์ฑ๋ฅ ํฅ์์ด ๋ฏธ๋ฏธํ๋ค๋ฉด ๊ฐ๋ ์ฑ์ ์ฐ์ ํ์ธ์.
๊ฐ์ธ ์คํฌ๋ฆฝํธ๋ฅผ ๋์ด ํ ํ๋ก์ ํธ๋ ํ๋ก๋์ ํ๊ฒฝ์์ R์ ์ฌ์ฉํ๋ ค๋ฉด ์ฒด๊ณ์ ์ธ ํ๋ก์ ํธ ๊ตฌ์กฐ๊ฐ ํ์ํฉ๋๋ค. ์ ๋ฌธ๊ฐ๋ค์ด ์ฌ์ฉํ๋ ๋ฒ ์คํธ ํ๋ํฐ์ค๋ฅผ ์๊ฐํฉ๋๋ค! ๐
my_project/
โโโ data/
โ โโโ raw/ # ์๋ณธ ๋ฐ์ดํฐ (์ ๋ ์์ ํ์ง ์์)
โ โโโ processed/ # ์ ์ฒ๋ฆฌ๋ ๋ฐ์ดํฐ
โ โโโ external/ # ์ธ๋ถ ๋ฐ์ดํฐ ์์ค
โโโ R/
โ โโโ 01_data_loading.R
โ โโโ 02_data_cleaning.R
โ โโโ 03_analysis.R
โ โโโ 04_visualization.R
โ โโโ functions.R # ์ฌ์ฌ์ฉ ํจ์๋ค
โโโ output/
โ โโโ figures/ # ์์ฑ๋ ๊ทธ๋ํ
โ โโโ tables/ # ๊ฒฐ๊ณผ ํ
์ด๋ธ
โ โโโ models/ # ์ ์ฅ๋ ๋ชจ๋ธ
โโโ reports/
โ โโโ analysis_report.Rmd
โ โโโ presentation.Rmd
โโโ tests/
โ โโโ test_functions.R # ๋จ์ ํ
์คํธ
โโโ .Rprofile # ํ๋ก์ ํธ ์ค์
โโโ config.yml # ์ค์ ํ์ผ
โโโ README.md # ํ๋ก์ ํธ ์ค๋ช
โโโ my_project.Rproj # RStudio ํ๋ก์ ํธ ํ์ผ
# config.yml ์์
default:
database:
host: localhost
port: 5432
name: analytics_db
paths:
data: "data/raw"
output: "output"
parameters:
test_size: 0.2
random_seed: 42
production:
database:
host: prod-server.company.com
port: 5432
name: prod_analytics_db
# R์์ ์ค์ ์ฝ๊ธฐ
library(config)
config <- config::get()
db_host <- config$database$host
# R/functions.R
#' ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ ํจ์
#'
#' @param df ๋ฐ์ดํฐ ํ๋ ์
#' @param cols ์ ์ฒ๋ฆฌํ ์ปฌ๋ผ๋ช
๋ฒกํฐ
#' @return ์ ์ฒ๋ฆฌ๋ ๋ฐ์ดํฐ ํ๋ ์
#' @export
preprocess_data <- function(df, cols) {
# ๊ฒฐ์ธก์น ์ฒ๋ฆฌ
df <- df %>%
mutate(across(all_of(cols), ~ifelse(is.na(.), median(., na.rm = TRUE), .)))
# ์ด์์น ์ฒ๋ฆฌ
df <- df %>%
mutate(across(all_of(cols), ~winsorize(., probs = c(0.01, 0.99))))
return(df)
}
#' ๋ชจ๋ธ ํ๊ฐ ์งํ ๊ณ์ฐ
#'
#' @param actual ์ค์ ๊ฐ
#' @param predicted ์์ธก ๊ฐ
#' @return ํ๊ฐ ์งํ ๋ฆฌ์คํธ
#' @export
calculate_metrics <- function(actual, predicted) {
list(
rmse = sqrt(mean((actual - predicted)^2)),
mae = mean(abs(actual - predicted)),
r_squared = cor(actual, predicted)^2
)
}
# ํจ์ ๋ก๋
source("R/functions.R")
---
title: "์๊ฐ ๋งค์ถ ๋ถ์ ๋ณด๊ณ ์"
author: "๋ฐ์ดํฐ ๋ถ์ํ"
date: "`r Sys.Date()`"
output:
html_document:
toc: true
toc_float: true
theme: cosmo
code_folding: hide
params:
start_date: "2024-01-01"
end_date: "2024-01-31"
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, warning = FALSE, message = FALSE)
library(tidyverse)
library(knitr)
library(kableExtra)
# ๋ฐ์ดํฐ ๋ก๋
sales_data <- read_csv("data/processed/sales.csv") %>%
filter(date >= params$start_date & date <= params$end_date)
```
## ์์ฝ
์ด๋ฒ ๋ฌ ์ด ๋งค์ถ์ **`r format(sum(sales_data$revenue), big.mark=",")`์**์
๋๋ค.
```{r sales_trend}
# ๋งค์ถ ์ถ์ด ๊ทธ๋ํ
ggplot(sales_data, aes(x = date, y = revenue)) +
geom_line() +
theme_minimal() +
labs(title = "์ผ๋ณ ๋งค์ถ ์ถ์ด")
```
## ์ง์ญ๋ณ ๋ถ์
```{r regional_analysis}
regional_summary <- sales_data %>%
group_by(region) %>%
summarise(
์ด๋งค์ถ = sum(revenue),
ํ๊ท ๋งค์ถ = mean(revenue),
๊ฑฐ๋๊ฑด์ = n()
)
kable(regional_summary, format.args = list(big.mark = ",")) %>%
kable_styling(bootstrap_options = c("striped", "hover"))
```
# .gitignore ์์
# R ๊ด๋ จ
.Rhistory
.RData
.Rproj.user/
# ๋ฐ์ดํฐ ํ์ผ (์ฉ๋์ด ํฐ ๊ฒฝ์ฐ)
data/raw/*.csv
data/processed/*.rds
# ์ถ๋ ฅ ํ์ผ
output/
*.pdf
*.html
# ๋ฏผ๊ฐํ ์ ๋ณด
config_local.yml
.env
# ์์ ํ์ผ
*~
.DS_Store
2. renv๋ก ํจํค์ง ๊ด๋ฆฌ: ํ๋ก์ ํธ๋ณ๋ก ํจํค์ง ๋ฒ์ ์ ๊ฒฉ๋ฆฌํด ์ฌํ์ฑ์ ๋ณด์ฅํ์ธ์.
3. ๋ฌธ์ํ: ํจ์์ roxygen2 ์ฃผ์์ ๋ฌ์ ์๋์ผ๋ก ๋ฌธ์๋ฅผ ์์ฑํ์ธ์.
4. ํ ์คํธ ์์ฑ: testthat ํจํค์ง๋ก ๋จ์ ํ ์คํธ๋ฅผ ์์ฑํด ์ฝ๋ ํ์ง์ ์ ์งํ์ธ์.
R์ ๋ฐฐ์ฐ๊ณ ๋ง์คํฐํ๋ ์ฌ์ ์์ ํผ์๊ฐ ์๋๋๋ค! ์ ์ธ๊ณ์ R ์ฌ์ฉ์๋ค์ด ๋ง๋ ํ๋ถํ ๋ฆฌ์์ค์ ํ๋ฐํ ์ปค๋ฎค๋ํฐ๊ฐ ์ฌ๋ฌ๋ถ์ ๊ธฐ๋ค๋ฆฌ๊ณ ์์ด์. ๐ค
2. ์ฝ๋ ๋ฆฌ๋ทฐ: Kaggle์ด๋ GitHub์์ ๊ณ ์๋ค์ ์ฝ๋๋ฅผ ์ฝ๊ณ ๋ถ์ํ์ธ์. ์๋ก์ด ๊ธฐ๋ฒ๊ณผ ํจํด์ ๋ฐฐ์ธ ์ ์์ต๋๋ค.
3. ์ปค๋ฎค๋ํฐ ์ฐธ์ฌ: ์ง๋ฌธํ๊ณ ๋ต๋ณํ๋ฉด์ ๋ฐฐ์ฐ์ธ์. ๊ฐ๋ฅด์น๋ ๊ฒ์ด ์ต๊ณ ์ ํ์ต๋ฒ์ ๋๋ค.
4. ์ฌ๋ฅ๋ท ํ์ฉ: ์ฌ๋ฅ๋ท์์ R ์ ๋ฌธ๊ฐ์ 1:1 ๋ฉํ ๋ง์ ๋ฐ์ผ๋ฉด ํ์ต ์๋๋ฅผ ํฌ๊ฒ ๋์ผ ์ ์์ต๋๋ค. ์ค๋ฌด ๊ฒฝํ์ด ํ๋ถํ ๋ฉํ ์๊ฒ ์ง์ ๋ฐฐ์ฐ๋ ๊ฒ๋งํผ ํจ๊ณผ์ ์ธ ๋ฐฉ๋ฒ์ ์์ฃ !
R์ 30๋ ๊ฐ๊น์ด ์ญ์ฌ๋ฅผ ๊ฐ์ง ์ธ์ด์ง๋ง, ์ฌ์ ํ ํ๋ฐํ๊ฒ ๋ฐ์ ํ๊ณ ์์ต๋๋ค. ์์ผ๋ก์ ํธ๋ ๋์ ๋ฐฉํฅ์ฑ์ ์ดํด๋ณผ๊น์? ๐
R์ ์ ์ ๋ ํด๋ผ์ฐ๋ ๋ค์ดํฐ๋ธํด์ง๊ณ ์์ต๋๋ค. AWS, Azure, GCP ๋ชจ๋ R์ ์ง์ํ๋ฉฐ, ๋น ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ฅ๋ ฅ๋ ๊ฐํ๋๊ณ ์์ฃ .
**์ฃผ์ ๋ฐ์ ๋ฐฉํฅ:** - sparklyr: Apache Spark์์ ์๋ฒฝํ ํตํฉ - bigrquery: Google BigQuery ์ง์ ์ฟผ๋ฆฌ - arrow: Apache Arrow๋ก ์ด๊ณ ์ ๋ฐ์ดํฐ ์ฒ๋ฆฌ - cloudml: ํด๋ผ์ฐ๋ ๊ธฐ๋ฐ ๋จธ์ ๋ฌ๋Shiny์ ๋ฐ์ ์ผ๋ก R์ ๋จ์ํ ๋ถ์ ๋๊ตฌ๋ฅผ ๋์ด ํ๋ก๋์ ์น ์ ํ๋ฆฌ์ผ์ด์ ํ๋ซํผ์ผ๋ก ์งํํ๊ณ ์์ต๋๋ค.
**์ต์ ํธ๋ ๋:** - Shiny for Python: Python๊ณผ์ ํตํฉ - golem: ํ๋ก๋์ ๊ธ Shiny ์ฑ ํ๋ ์์ํฌ - shinytest2: ์๋ํ๋ ํ ์คํ - Plumber: RESTful API ๊ฐ๋ฐR์ ์ต์ ๋จธ์ ๋ฌ๋ ๊ธฐ๋ฒ์ ๋๊ตฌ๋ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๊ฒ ๋ง๋๋ ๋ฐ ์ฃผ๋ ฅํ๊ณ ์์ต๋๋ค.
**์ฃผ๋ชฉํ ํจํค์ง:** - tidymodels: ํต์ผ๋ ๋ชจ๋ธ๋ง ํ๋ ์์ํฌ - mlr3: ์ฐจ์ธ๋ ๋จธ์ ๋ฌ๋ ํ๋ ์์ํฌ - torch: PyTorch์ R ๋ฒ์ - luz: ๊ณ ์์ค ๋ฅ๋ฌ๋ API๊ณผํ ์ฐ๊ตฌ์ ์ฌํ์ฑ ์๊ธฐ์ ๋์ํด, R์ ์์ ํ ์ฌํ ๊ฐ๋ฅํ ๋ถ์ ํ๊ฒฝ์ ์ ๊ณตํ๋ ๋ฐ ์์ฅ์๊ณ ์์ต๋๋ค.
**ํต์ฌ ๋๊ตฌ:** - renv: ํจํค์ง ๋ฒ์ ๊ด๋ฆฌ - targets: ๋ถ์ ํ์ดํ๋ผ์ธ ๊ด๋ฆฌ - Docker: ์ปจํ ์ด๋ํ๋ R ํ๊ฒฝ - Binder: ํด๋ผ์ฐ๋์์ ์ฌํ ๊ฐ๋ฅํ ํ๊ฒฝIoT์ ์ค์๊ฐ ๋ถ์์ ์๋์ ๋ง์ถฐ, R๋ ์คํธ๋ฆฌ๋ฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ฅ๋ ฅ์ ๊ฐํํ๊ณ ์์ต๋๋ค.
**๋ฐ์ ์์ญ:** - ์ค์๊ฐ ๋์๋ณด๋ - ์คํธ๋ฆฌ๋ฐ ๋ฐ์ดํฐ ๋ถ์ - ์ด๋ฒคํธ ๊ธฐ๋ฐ ์ฒ๋ฆฌ - ์ค์๊ฐ ๋จธ์ ๋ฌ๋ ๋ชจ๋ธ ์ ๋ฐ์ดํธ์ฌ๊ธฐ๊น์ง R ์ธ์ด์ ๋ฐฉ๋ํ ์ธ๊ณ๋ฅผ ํจ๊ป ํํํ์ต๋๋ค. ํต๊ณ ๋ถ์์ ๊ธฐ์ด๋ถํฐ ๋จธ์ ๋ฌ๋, ์๊ฐํ, ํ๋ก๋์ ๋ฐฐํฌ๊น์ง... R์ ์ ๋ง ๋ค์ฌ๋ค๋ฅํ ๋๊ตฌ์ฃ ! ๐
R์ ๋ฐฐ์ฐ๋ ๊ฒ์ ๋จ์ํ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด ํ๋๋ฅผ ์ตํ๋ ๊ฒ์ด ์๋๋๋ค. ๋ฐ์ดํฐ๋ฅผ ํตํด ์ธ์์ ์ดํดํ๊ณ , ์ธ์ฌ์ดํธ๋ฅผ ๋ฐ๊ฒฌํ๊ณ , ์์ฌ๊ฒฐ์ ์ ๊ฐ์ ํ๋ **๊ฐ๋ ฅํ ๋ฌด๊ธฐ**๋ฅผ ์์ ๋ฃ๋ ๊ฒ์ ๋๋ค. ๐
R์ ์ฒ์ ์์ํ๋ ๋ถ๋ค๊ป ๋๋ฆฌ๋ ์กฐ์ธ์ด ์์ต๋๋ค:
**1. ์๋ฒฝ์ ์ถ๊ตฌํ์ง ๋ง์ธ์** ๐ฏ์ฒ์๋ถํฐ ๋ชจ๋ ๊ฒ์ ์ ํ์๋ ์์ต๋๋ค. ํ์ํ ๊ฒ๋ถํฐ ๋ฐฐ์ฐ๊ณ , ์ ์ง์ ์ผ๋ก ํ์ฅํ์ธ์. ์๋ฌ ๋ฉ์์ง๋ ์น๊ตฌ์ ๋๋ค!
**2. ์ค์ ๋ฐ์ดํฐ๋ก ์ฐ์ตํ์ธ์** ๐ช๊ด์ฌ ์๋ ๋ถ์ผ์ ๋ฐ์ดํฐ๋ฅผ ์ฐพ์ ์ง์ ๋ถ์ํด๋ณด์ธ์. ์ด๋ก ๋ง ๊ณต๋ถํ๋ ๊ฒ๋ณด๋ค 100๋ฐฐ ํจ๊ณผ์ ์ ๋๋ค.
**3. ์ปค๋ฎค๋ํฐ๋ฅผ ํ์ฉํ์ธ์** ๐ค๋งํ ๋๋ ์ฃผ์ ํ์ง ๋ง๊ณ ์ง๋ฌธํ์ธ์. R ์ปค๋ฎค๋ํฐ๋ ์ด๋ณด์์๊ฒ ๋งค์ฐ ์น์ ํฉ๋๋ค.
**4. ๊พธ์คํจ์ด ํต์ฌ์ ๋๋ค** ๐ฅ๋งค์ผ ์กฐ๊ธ์ฉ์ด๋ผ๋ ์ฝ๋๋ฅผ ์์ฑํ์ธ์. ํ ๋ฌ๋ง ๊พธ์คํ ํ๋ฉด ๋๋ผ์ด ๋ฐ์ ์ ๊ฒฝํํ ๊ฒ๋๋ค.
**5. ์ ๋ฌธ๊ฐ์ ๋์์ ๋ฐ์ผ์ธ์** ๐ํผ์ ๊ณต๋ถํ๋ค ๋งํ ๋๋ ์ฌ๋ฅ๋ท ๊ฐ์ ํ๋ซํผ์์ ์ ๋ฌธ๊ฐ์ ๋ฉํ ๋ง์ ๋ฐ๋ ๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ ๋๋ค. ์ค๋ฌด ๊ฒฝํ์ด ํ๋ถํ ๋ฉํ ๊ฐ ์ฌ๋ฌ๋ถ์ ํ์ต ์๋๋ฅผ ํฌ๊ฒ ๋์ฌ์ค ์ ์์ด์!
๐ ์ถํํฉ๋๋ค!
์ด์ ์ฌ๋ฌ๋ถ์ R ์ธ์ด์ ๋ฐฉ๋ํ ์ธ๊ณ๋ฅผ ์ดํดํ๊ฒ ๋์์ต๋๋ค. ํต๊ณ ๋ถ์๋ถํฐ ๋จธ์ ๋ฌ๋, ์๊ฐํ, ํ๋ก๋์
๋ฐฐํฌ๊น์ง... R์ ๋ฐ์ดํฐ ์ฌ์ด์ธ์ค์ ๋ชจ๋ ๋จ๊ณ๋ฅผ ์ปค๋ฒํ๋ ๊ฐ๋ ฅํ ๋๊ตฌ์
๋๋ค.
๊ธฐ์ตํ์ธ์: ๋ชจ๋ ์ ๋ฌธ๊ฐ๋ ์ฒ์์๋ ์ด๋ณด์์์ต๋๋ค. ์ค์ํ ๊ฒ์ ์์ํ๋ ๊ฒ์ด๊ณ , ๊พธ์คํ ๋์๊ฐ๋ ๊ฒ์
๋๋ค. ์ฌ๋ฌ๋ถ์ R ์ฌ์ ์ ์์ํฉ๋๋ค! ๐ชโจ
๋ฐ์ดํฐ๋ก ์ธ์์ ๋ฐ๊พธ๋ ์ฌ๋ฌ๋ถ์ ์ฌ์ , R๊ณผ ํจ๊ป๋ผ๋ฉด ๋์ฑ ์ฆ๊ฒ๊ณ ํจ๊ณผ์ ์ผ ๊ฒ์
๋๋ค! ๐๐
Happy Coding with R! ๐ปโจ
๊ด๋ จ ํค์๋
๋๊ธ ์์ฑ
์ด ๊ธ์ ๋ํ ์ฌ๋ฌ๋ถ์ ์๊ฐ์ ๋ค๋ ค์ฃผ์ธ์
๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค
๋๊ธ์ ์์ฑํ๋ ค๋ฉด ๋จผ์ ๋ก๊ทธ์ธํด์ฃผ์ธ์.
๋๊ธ 0
์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
์์ง ๋๊ธ์ด ์์ต๋๋ค.