상관분석은 두 변수 간의 관계 강도와 방향을 측정하고, 단순 회귀분석은 한 변수(독립 변수)를 사용해 다른 변수(종속 변수)를 예측하는 모형으로 상관분석은 두 변수 간의 관계 강도와 방향을 측정하는 데 중점을 두고, 회귀분석은 한 변수를 사용해 다른 변수를 예측하는 데 중점을 둔다. 특히 상관계수의 제곱은 회귀 분석에서 결정계수로 해석된다.
#| label: shinylive-reg-simple
#| viewerHeight: 700
#| standalone: true
library(shiny)
library(showtext)
showtext_auto()
library(bslib)
library(showtext)
tryCatch(sysfonts::font_add_google("Nanum Myeongjo", "kr"), error = function(e) NULL)
showtext_auto()
# ── Tufte 팔레트 · 테마 (자동 주입) ──────────────────────────
bit_cream <- "#fffff8"; bit_ink <- "#111111"; bit_rust <- "#8a1500"
bit_muted <- "#4a4a44"; bit_grid <- "#e8e6dc"; bit_axis <- "#8a8578"
theme_tufte_bit <- function(base_size = 13) {
ggplot2::theme_minimal(base_size = base_size) +
ggplot2::theme(
text = ggplot2::element_text(family = "kr", colour = bit_ink),
plot.title = ggplot2::element_text(family = "kr", size = base_size, hjust = 0),
plot.background = ggplot2::element_rect(fill = bit_cream, colour = NA),
panel.background = ggplot2::element_rect(fill = bit_cream, colour = NA),
panel.grid.major = ggplot2::element_line(colour = bit_grid, linewidth = 0.3),
panel.grid.minor = ggplot2::element_blank(),
axis.line = ggplot2::element_line(colour = bit_axis, linewidth = 0.3),
axis.ticks = ggplot2::element_line(colour = bit_axis, linewidth = 0.3)
)
}
if (requireNamespace("ggplot2", quietly = TRUE)) ggplot2::theme_set(theme_tufte_bit())
bit_theme <- bs_theme(
version = 5, bg = bit_cream, fg = bit_ink, primary = bit_rust,
base_font = font_collection("Palatino Linotype", "Georgia", "Times New Roman", "serif"),
"card-box-shadow" = "none"
)
# ─────────────────────────────────────────────────────────────
ui <- fluidPage(
theme = bit_theme,
titlePanel("상관분석과 단순 회귀분석"),
sidebarLayout(
sidebarPanel(
fileInput("file", "CSV 파일 업로드", accept = c("text/csv", "text/comma-separated-values,text/plain", ".csv")),
radioButtons("dataset", "데이터셋 선택:",
choices = c("mtcars", "USArrests", "업로드 데이터셋"),
selected = "mtcars"),
selectInput("y_var", "Y 변수 (종속변수):", ""),
selectInput("x_var", "X 변수 (독립변수):", "")
),
mainPanel(
tabsetPanel(
tabPanel("산점도", plotOutput("scatterplot")),
tabPanel("상관계수",
verbatimTextOutput("correlation"),
verbatimTextOutput("cor_test")),
tabPanel("회귀분석", verbatimTextOutput("regression"))
)
)
)
)
server <- function(input, output, session) {
data <- reactive({
if (input$dataset == "업로드 데이터셋") {
req(input$file)
read.csv(input$file$datapath, header = TRUE)
} else {
switch(input$dataset,
"mtcars" = mtcars,
"USArrests" = USArrests)
}
})
observe({
choices <- names(data())[sapply(data(), is.numeric)]
updateSelectInput(session, "y_var", choices = choices)
updateSelectInput(session, "x_var", choices = choices)
})
output$scatterplot <- renderPlot({
req(input$y_var, input$x_var)
plot(data()[[input$x_var]], data()[[input$y_var]],
xlab = input$x_var, ylab = input$y_var,
main = "회귀선이 포함된 산점도")
abline(lm(data()[[input$y_var]] ~ data()[[input$x_var]]), col = "#8a1500", lwd = 2)
legend("topleft", legend = "회귀선", col = "#8a1500", lwd = 2, bty = "n")
})
output$correlation <- renderPrint({
req(input$y_var, input$x_var)
cor_val <- cor(data()[[input$x_var]], data()[[input$y_var]])
det_coef <- cor_val^2
cat("상관계수:", round(cor_val, 3), "\n")
cat("결정계수 (R-squared):", round(det_coef, 3))
})
output$cor_test <- renderPrint({
req(input$y_var, input$x_var)
cor.test(data()[[input$x_var]], data()[[input$y_var]])
})
output$regression <- renderPrint({
req(input$y_var, input$x_var)
lm_model <- lm(data()[[input$y_var]] ~ data()[[input$x_var]])
names(lm_model$coefficients) <- c("절편", input$x_var)
summary(lm_model)
})
}
shinyApp(ui, server)