2표본 t-검정은 두 독립적인 그룹의 평균 차이가 통계적으로 유의미한지를 판단하기 위한 통계적 검정 방법이다. 이 검정은 두 집단이 정규분포를 따르고, 데이터가 독립적인 경우에 사용할 수 있다.
검정을 수행할 때 두 그룹의 분산이 같은지 다른지에 따라 검정 방법이 달라진다. 분산이 같다고 가정할 경우 등분산을 가정하는 t-검정을 사용하고, 분산이 다르다고 가정할 경우 등분산이 아닌 t-검정을 사용한다. R에서는 t.test()
함수를 사용하여 이 두 경우를 쉽게 계산할 수 있다. var.equal = TRUE
옵션을 사용하면 등분산을 가정하는 t-검정을 수행하고, var.equal = FALSE
옵션을 사용하면 등분산이 아닌 t-검정을 수행한다.
1 Shiny 앱
#| label: shinylive-prob-law
#| viewerWidth: 800
#| viewerHeight: 600
#| standalone: true
library(ggplot2)
library(showtext)
library(gt)
# font_add_google(name = "Nanum Gothic", regular.wt = 400)
showtext_auto()
# 3. 2-표본 t-검정---------------
t.test3 <- function(x, y, V1, V2, m0 = 0, alpha = 0.05, alternative = "two.sided") {
M1 <- mean(x)
M2 <- mean(y)
n1 <- length(x)
n2 <- length(y)
sigma1 <- sqrt(V1)
sigma2 <- sqrt(V2)
S <- sqrt((V1 / n1) + (V2 / n2))
statistic <- (M1 - M2 - m0) / S
p <- if (alternative == "two.sided") {
2 * pnorm(abs(statistic), lower.tail = FALSE)
} else if (alternative == "less") {
pnorm(statistic, lower.tail = TRUE)
} else {
pnorm(statistic, lower.tail = FALSE)
}
# p <- (1 - pnorm((M-m0)/S))
LCL <- (M1 - M2 - S * qnorm(1 - alpha / 2))
UCL <- (M1 - M2 + S * qnorm(1 - alpha / 2))
value <- list(mean1 = M1, mean2 = M2, m0 = m0, sigma1 = sigma1, sigma2 = sigma2, S = S, statistic = statistic, p.value = p, LCL = LCL, UCL = UCL, alternative = alternative)
# print(sprintf("P-value = %g",p))
# print(sprintf("Lower %.2f%% Confidence Limit = %g",
# alpha, LCL))
# print(sprintf("Upper %.2f%% Confidence Limit = %g",
# alpha, UCL))
return(value)
}
two_means_UI <- function(id) {
ns <- NS(id)
# 1. 메인 패널 ------------------------------------
mainPanel <- mainPanel(
tabsetPanel(
tabPanel("검정 결과", uiOutput(ns("results_twomean"))),
tabPanel("시각화", plotOutput(ns("plot_twomean"))),
tabPanel("데이터", gt_output(ns("table_twomean")))
)
)
# 2. 옆 패널 --------------------------------------
sidebarPanel <- sidebarPanel(width = 4,
tags$br(),
tags$h4("* 데이터"),
textInput(ns("twomeans_sample1"), "표본 1", value = "0.9, -0.8, 0.1, -0.3, 0.2"),
textInput(ns("twomeans_sample2"), "표본 2", value = "0.8, -0.9, -0.1, 0.4, 0.1"),
tags$p("※ 콤마로 구분된 숫자 입력. ex) 7.2, 4.7, 5.03, 등"),
tags$p("모집단 분산"),
radioButtons(
inputId = ns("twomeans_var.equal"),
label = "분산에 대한 가정:",
choices = c(
"\\( \\sigma^2_1 = \\sigma^2_2 \\)" = TRUE,
"\\( \\sigma^2_1 \\neq \\sigma^2_2 \\)" = FALSE
)
),
checkboxInput(ns("twomeans_popsd"), "모집단 분산을 알는 경우:", FALSE),
conditionalPanel(
# condition = "input.twomeans_popsd == 1",
condition = paste0("input['", ns("twomeans_popsd"), "'] == 1"),
numericInput(ns("twomeans_sigma21"), "\\(\\sigma^2_1 = \\)",
value = 1, min = 0, step = 1, width = "100px"
),
numericInput(ns("twomeans_sigma22"), "\\(\\sigma^2_2 = \\)",
value = 1, min = 0, step = 1, width = "100px"
)
),
tags$h4("* 가설검정"),
tags$p("1. 귀무가설"),
tags$p("\\( H_0 : \\mu_1 - \\mu_2 = \\)"),
numericInput(ns("twomeans_h0"),
label = NULL,
value = 0, step = 0.1, width="100px"),
tags$p("2. 검정방향"),
radioButtons(
inputId = ns("twomeans_alternative"),
label = "대립가설",
inline = TRUE,
choices = c(
"\\( \\neq \\)" = "two.sided",
"\\( > \\)" = "greater",
"\\( < \\)" = "less"
)
),
tags$p("3. 유의수준"),
sliderInput(ns("twomeans_alpha"),
"유의수준 \\(\\alpha = \\)",
min = 0.01,
max = 0.10,
step = 0.01,
value = 0.05
)
)
# 3. 레이아웃 -----------------------------------------------------------
tagList(
withMathJax(),
tags$div(
fluidPage(
theme = shinythemes::shinytheme("flatly"),
sidebarPanel,
mainPanel
)
)
)
}
two_means_server <- function(id) {
moduleServer(id, function(input, output, session) {
output$results_twomean <- renderUI({
dat1 <- as.numeric(unlist(strsplit(input$twomeans_sample1, ",")))
dat2 <- as.numeric(unlist(strsplit(input$twomeans_sample2, ",")))
if (anyNA(dat1) | length(dat1) < 2 | anyNA(dat2) | length(dat2) < 2) {
"Invalid input or not enough observations"
} else if ( input$twomeans_popsd == FALSE & input$twomeans_var.equal == TRUE ){
test_confint <- t.test(x = dat1, y = dat2, mu = input$twomeans_h0, alternative = "two.sided", conf.level = 1 - input$twomeans_alpha, paired = FALSE, var.equal = TRUE)
test <- t.test(x = dat1, y = dat2, mu = input$twomeans_h0, alternative = input$twomeans_alternative, conf.level = 1 - input$twomeans_alpha, paired = FALSE, var.equal = TRUE)
s_p <- sqrt(((length(dat1) - 1) * var(dat1) + (length(dat2) - 1) * var(dat2)) / test_confint$parameter)
withMathJax(
tags$h2("데이터"),
br(),
paste(c("\\(표본_1=\\)", paste(dat1, collapse = ", ")), collapse = " "),
br(),
paste(c("\\(표본_2=\\)", paste(dat2, collapse = ", ")), collapse = " "),
br(),
paste0("\\(n_1 =\\) ", length(dat1)),
br(),
paste0("\\(n_2 =\\) ", length(dat2)),
br(),
paste0("\\(\\bar{x}_1 =\\) ", round(mean(dat1), 3)),
br(),
paste0("\\(\\bar{x}_2 =\\) ", round(mean(dat2), 3)),
br(),
paste0("\\(s^2_1 =\\) ", round(var(dat1), 3)),
br(),
paste0("\\(s^2_2 =\\) ", round(var(dat2), 3)),
br(),
br(),
tags$h2("신뢰구간 - 양측"),
br(),
paste0((1 - input$twomeans_alpha) * 100, "% CI 신뢰구간: \\(\\mu_1 - \\mu_2 = \\bar{x}_1 - \\bar{x}_2 \\pm t_{\\alpha/2, n_1 + n_2 - 2} (s_p) \\sqrt{\\dfrac{1}{n_1} + \\dfrac{1}{n_2}} \\)"),
br(),
paste0("where ", "\\( s_p = \\sqrt{\\dfrac{(n_1 - 1)s^2_1 + (n_2 - 1)s^2_2}{n_1 + n_2 - 2}} = \\) ", round(s_p, 3)),
br(),
br(),
paste0(
"\\( \\Rightarrow \\)", (1 - input$twomeans_alpha) * 100, "% CI 신뢰구간: \\(\\mu_1 - \\mu_2 = \\) ", round(test_confint$estimate[1], 3), ifelse(test_confint$estimate[2] >= 0, paste0(" - ", round(test_confint$estimate[2], 3)), paste0(" + ", round(abs(test_confint$estimate[2]), 3))), " \\( \\pm \\) ", "\\( (\\)", round(qt(input$twomeans_alpha / 2, df = test_confint$parameter, lower.tail = FALSE), 3), " * ", round(s_p, 3), " * ", round(sqrt(1 / length(dat1) + 1 / length(dat2)), 3), "\\( ) \\) ", "\\( = \\) ",
"[", round(test_confint$conf.int[1], 3), "; ", round(test_confint$conf.int[2], 3), "]"
),
br(),
br(),
tags$h2("가설 검정"),
br(),
paste0("1. \\(H_0 : \\mu_1 - \\mu_2 = \\) ", test$null.value, " and \\(H_1 : \\mu_1 - \\mu_2 \\) ", ifelse(input$twomeans_alternative == "two.sided", "\\( \\neq \\) ", ifelse(input$twomeans_alternative == "greater", "\\( > \\) ", "\\( < \\) ")), test$null.value),
br(),
paste0(
"2. 검정 통계량 : \\(t_{obs} = \\dfrac{(\\bar{x}_1 - \\bar{x}_2) - (\\mu_1 - \\mu_2)}{s_p \\sqrt{\\dfrac{1}{n_1} + \\dfrac{1}{n_2}}} = \\) ",
"(", round(test$estimate[1], 3), ifelse(test$estimate[2] >= 0, paste0(" - ", round(test$estimate[2], 3)), paste0(" + ", round(abs(test$estimate[2]), 3))), ifelse(test$null.value >= 0, paste0(" - ", test$null.value), paste0(" + ", abs(test$null.value))), ") / (", round(s_p, 3), " * ", round(sqrt((1 / length(dat1)) + (1 / length(dat2))), 3), ") \\( = \\) ",
round(test$statistic, 3)
),
br(),
paste0(
"3. 임계값 :", ifelse(input$twomeans_alternative == "two.sided", " \\( \\pm t_{\\alpha/2, n_1 + n_2 - 2} = \\pm t(\\)", ifelse(input$twomeans_alternative == "greater", " \\( t_{\\alpha, n_1 + n_2 - 2} = t(\\)", " \\( -t_{\\alpha, n_1 + n_2 - 2} = -t(\\)")),
ifelse(input$twomeans_alternative == "two.sided", input$twomeans_alpha / 2, input$twomeans_alpha), ", ", test$parameter, "\\()\\)", " \\( = \\) ",
ifelse(input$twomeans_alternative == "two.sided", "\\( \\pm \\)", ifelse(input$twomeans_alternative == "greater", "", " -")),
ifelse(input$twomeans_alternative == "two.sided", round(qt(input$twomeans_alpha / 2, df = test$parameter, lower.tail = FALSE), 3), round(qt(input$twomeans_alpha, df = test$parameter, lower.tail = FALSE), 3))
),
br(),
paste0("4. 결론 : ", ifelse(test$p.value < input$twomeans_alpha, "\\(H_0\\) 기각.", "\\(H_0\\) 기각 못함")),
br(),
br(),
tags$h2("해석"),
br(),
paste0( input$twomeans_alpha * 100, "% 유의수준에서, ",
"평균 차이가 ", test$null.value, " 이라는 귀무가설을 ",
ifelse(test$p.value < input$twomeans_alpha, "기각한다", "기각하지 않는다"),
" \\((p\\)-값 ", ifelse(test$p.value < 0.001, "< 0.001", paste0("\\(=\\) ", round(test$p.value, 3))), ")", ".")
)
} else if ( input$twomeans_popsd == FALSE & input$twomeans_var.equal == FALSE) {
test_confint <- t.test(x = dat1, y = dat2, mu = input$twomeans_h0, alternative = "two.sided", conf.level = 1 - input$twomeans_alpha, paired = FALSE, var.equal = FALSE)
test <- t.test(x = dat1, y = dat2, mu = input$twomeans_h0, alternative = input$twomeans_alternative, conf.level = 1 - input$twomeans_alpha, paired = FALSE, var.equal = FALSE)
withMathJax(
tags$h2("데이터"),
br(),
paste(c("\\(표본_1=\\)", paste(dat1, collapse = ", ")), collapse = " "),
br(),
paste(c("\\(표본_2=\\)", paste(dat2, collapse = ", ")), collapse = " "),
br(),
paste0("\\(n_1 =\\) ", length(dat1)),
br(),
paste0("\\(n_2 =\\) ", length(dat2)),
br(),
paste0("\\(\\bar{x}_1 =\\) ", round(mean(dat1), 3)),
br(),
paste0("\\(\\bar{x}_2 =\\) ", round(mean(dat2), 3)),
br(),
paste0("\\(s^2_1 =\\) ", round(var(dat1), 3)),
br(),
paste0("\\(s^2_2 =\\) ", round(var(dat2), 3)),
br(),
br(),
tags$h2("신뢰구간 - 양측"),
br(),
paste0((1 - input$twomeans_alpha) * 100, "% CI 신뢰구간: \\(\\mu_1 - \\mu_2 = \\bar{x}_1 - \\bar{x}_2 \\pm t_{\\alpha/2, \\nu} \\sqrt{\\dfrac{s^2_1}{n_1} + \\dfrac{s^2_2}{n_2}} \\)"),
br(),
paste0("여기서, ", "\\( \\nu = \\dfrac{\\Bigg(\\dfrac{s^2_1}{n_1} + \\dfrac{s^2_2}{n_2}\\Bigg)^2}{\\dfrac{\\Bigg(\\dfrac{s^2_1}{n_1}\\Bigg)^2}{n_1-1} + \\dfrac{\\Bigg(\\dfrac{s^2_2}{n_2}\\Bigg)^2}{n_2-1}} = \\) ", round(test$parameter, 3)),
br(),
br(),
paste0(
"\\( \\Rightarrow \\)", (1 - input$twomeans_alpha) * 100, "% CI 신뢰구간: \\(\\mu_1 - \\mu_2 = \\) ", round(test_confint$estimate[1], 3), ifelse(test_confint$estimate[2] >= 0, paste0(" - ", round(test_confint$estimate[2], 3)), paste0(" + ", round(abs(test_confint$estimate[2]), 3))), " \\( \\pm \\) ", "\\( (\\)",round(qt(input$twomeans_alpha / 2, df = test_confint$parameter, lower.tail = FALSE), 3), " * ", round(test_confint$stderr, 3), "\\( ) \\) ", "\\( = \\) ",
"[", round(test_confint$conf.int[1], 3), "; ", round(test_confint$conf.int[2], 3), "]"
),
br(),
br(),
tags$em(paste0("주의: 자유도를 df = \\(min(n_1 - 1, n_2 - 1) \\) 으로 단순하게 근사화해서 구함, 그래서 이 경우에 df = ",
min(length(dat1) - 1, length(dat2) - 1), ".")),
br(),
br(),
tags$h2("가설 검정"),
br(),
paste0("1. \\(H_0 : \\mu_1 - \\mu_2 = \\) ", test$null.value, " and \\(H_1 : \\mu_1 - \\mu_2 \\) ", ifelse(input$twomeans_alternative == "two.sided", "\\( \\neq \\) ", ifelse(input$twomeans_alternative == "greater", "\\( > \\) ", "\\( < \\) ")), test$null.value),
br(),
paste0(
"2. 검정 통계량 : \\(t_{obs} = \\dfrac{(\\bar{x}_1 - \\bar{x}_2) - (\\mu_1 - \\mu_2)}{\\sqrt{\\dfrac{s^2_1}{n_1} + \\dfrac{s^2_2}{n_2}}} = \\) ",
"(", round(test$estimate[1], 3), ifelse(test$estimate[2] >= 0, paste0(" - ", round(test$estimate[2], 3)), paste0(" + ", round(abs(test$estimate[2]), 3))), ifelse(test$null.value >= 0, paste0(" - ", test$null.value), paste0(" + ", abs(test$null.value))), ") / ", round(test$stderr, 3), " \\( = \\) ",
round(test$statistic, 3)
),
br(),
paste0(
"3. 임계값 :", ifelse(input$twomeans_alternative == "two.sided", " \\( \\pm t_{\\alpha/2, \\nu} = \\pm t(\\)", ifelse(input$twomeans_alternative == "greater", " \\( t_{\\alpha, \\nu} = t(\\)", " \\( -t_{\\alpha, \\nu} = -t(\\)")),
ifelse(input$twomeans_alternative == "two.sided", input$twomeans_alpha / 2, input$twomeans_alpha), ", ", round(test$parameter, 3), "\\()\\)", " \\( = \\) ",
ifelse(input$twomeans_alternative == "two.sided", "\\( \\pm \\)", ifelse(input$twomeans_alternative == "greater", "", " -")),
ifelse(input$twomeans_alternative == "two.sided", round(qt(input$twomeans_alpha / 2, df = test$parameter, lower.tail = FALSE), 3), round(qt(input$twomeans_alpha, df = test$parameter, lower.tail = FALSE), 3))
),
br(),
paste0("4. 결론 : ", ifelse(test$p.value < input$twomeans_alpha, "\\(H_0\\) 기각.", "\\(H_0\\) 기각 못함")),
br(),
br(),
tags$h2("해석"),
br(),
paste0( input$twomeans_alpha * 100, "% 유의수준에서, ",
"평균 차이가 ", test$null.value, " 이라는 귀무가설을 ",
ifelse(test$p.value < input$twomeans_alpha, "기각한다", "기각하지 않는다"),
" \\((p\\)-값 ", ifelse(test$p.value < 0.001, "< 0.001", paste0("\\(=\\) ", round(test$p.value, 3))), ")", ".")
)
} else if ( input$twomeans_popsd == TRUE) {
test <- t.test3(x = dat1, y = dat2, V1 = input$twomeans_sigma21, V2 = input$twomeans_sigma22, m0 = input$twomeans_h0, alpha = input$twomeans_alpha, alternative = input$twomeans_alternative)
withMathJax(
tags$h2("데이터"),
br(),
paste(c("\\(표본_1=\\)", paste(dat1, collapse = ", ")), collapse = " "),
br(),
paste(c("\\(표본_2=\\)", paste(dat2, collapse = ", ")), collapse = " "),
br(),
paste0("\\(n_1 =\\) ", length(dat1)),
br(),
paste0("\\(n_2 =\\) ", length(dat2)),
br(),
paste0("\\(\\bar{x}_1 =\\) ", round(mean(dat1), 3)),
br(),
paste0("\\(\\bar{x}_2 =\\) ", round(mean(dat2), 3)),
br(),
paste0("\\(\\sigma^2_1 =\\) ", round(input$twomeans_sigma21, 3)),
br(),
paste0("\\(\\sigma^2_2 =\\) ", round(input$twomeans_sigma22, 3)),
br(),
br(),
tags$h2("신뢰구간 - 양측"),
br(),
paste0(
(1 - input$twomeans_alpha) * 100, "% Confidence Interval for \\(\\mu_1 - \\mu_2 = \\bar{x}_1 - \\bar{x}_2 \\pm z_{\\alpha/2} \\sqrt{\\dfrac{\\sigma^2_1}{n_1} + \\dfrac{\\sigma^2_2}{n_2}} = \\) ",
round(test$mean1, 3), ifelse(test$mean2 >= 0, paste0(" - ", round(test$mean2, 3)), paste0(" + ", round(abs(test$mean2), 3))), " \\( \\pm \\)", " \\( ( \\)", round(qnorm(input$twomeans_alpha / 2, lower.tail = FALSE), 3), " * ", round(test$S, 3), "\\( ) \\) ", "\\( = \\) ",
"[", round(test$LCL, 3), "; ", round(test$UCL, 3), "]"
),
br(),
br(),
tags$h2("가설 검정"),
br(),
paste0("1. \\(H_0 : \\mu_1 - \\mu_2 = \\) ", input$twomeans_h0, " and \\(H_1 : \\mu_1 - \\mu_2 \\) ", ifelse(input$twomeans_alternative == "two.sided", "\\( \\neq \\) ", ifelse(input$twomeans_alternative == "greater", "\\( > \\) ", "\\( < \\) ")), input$twomeans_h0),
br(),
paste0(
"2. 검정 통계량 : \\(z_{obs} = \\dfrac{(\\bar{x}_1 - \\bar{x}_2) - (\\mu_1 - \\mu_2)}{\\sqrt{\\dfrac{\\sigma^2_1}{n_1} + \\dfrac{\\sigma^2_2}{n_2}}} = \\) ",
"(", round(test$mean1, 3), ifelse(test$mean2 >= 0, paste0(" - ", round(test$mean2, 3)), paste0(" + ", round(abs(test$mean2), 3))), ifelse(input$twomeans_h0 >= 0, paste0(" - ", input$twomeans_h0), paste0(" + ", abs(input$twomeans_h0))), ") / ", round(test$S, 3), " \\( = \\) ",
round(test$statistic, 3)
),
br(),
paste0(
"3. 임계값 :", ifelse(input$twomeans_alternative == "two.sided", " \\( \\pm z_{\\alpha/2} = \\pm z(\\)", ifelse(input$twomeans_alternative == "greater", " \\( z_{\\alpha} = z(\\)", " \\( -z_{\\alpha} = -z(\\)")),
ifelse(input$twomeans_alternative == "two.sided", input$twomeans_alpha / 2, input$twomeans_alpha), "\\()\\)", " \\( = \\) ",
ifelse(input$twomeans_alternative == "two.sided", "\\( \\pm \\)", ifelse(input$twomeans_alternative == "greater", "", " -")),
ifelse(input$twomeans_alternative == "two.sided", round(qnorm(input$twomeans_alpha / 2, lower.tail = FALSE), 3), round(qnorm(input$twomeans_alpha, lower.tail = FALSE), 3))
),
br(),
paste0("4. 결론 : ", ifelse(test$p.value < input$twomeans_alpha, "\\(H_0\\) 기각.", "\\(H_0\\) 기각 못함")),
br(),
br(),
tags$h2("해석"),
br(),
paste0( input$twomeans_alpha * 100, "% 유의수준에서, ",
"평균 차이가 ", test$null.value, " 이라는 귀무가설을 ",
ifelse(test$p.value < input$twomeans_alpha, "기각한다", "기각하지 않는다"),
" \\((p\\)-값 ", ifelse(test$p.value < 0.001, "< 0.001", paste0("\\(=\\) ", round(test$p.value, 3))), ")", ".")
)
}
})
output$plot_twomean <- renderPlot({
if ( input$twomeans_popsd == FALSE & input$twomeans_var.equal == TRUE) {
dat1 <- as.numeric(unlist(strsplit(input$twomeans_sample1, ",")))
dat2 <- as.numeric(unlist(strsplit(input$twomeans_sample2, ",")))
test <- t.test(x = dat1, y = dat2, mu = input$twomeans_h0, alternative = input$twomeans_alternative, conf.level = 1 - input$twomeans_alpha, paired = FALSE, var.equal = TRUE)
if (input$twomeans_alternative == "two.sided") {
funcShaded <- function(x) {
y <- dt(x, df = test$parameter)
y[x < qt(input$twomeans_alpha / 2, df = test$parameter, lower.tail = FALSE) & x > qt(input$twomeans_alpha / 2, df = test$parameter, lower.tail = TRUE) ] <- NA
return(y)
}
} else if (input$twomeans_alternative == "greater") {
funcShaded <- function(x) {
y <- dt(x, df = test$parameter)
y[x < qt(input$twomeans_alpha, df = test$parameter, lower.tail = FALSE) ] <- NA
return(y)
}
} else if (input$twomeans_alternative == "less") {
funcShaded <- function(x) {
y <- dt(x, df = test$parameter)
y[x > qt(input$twomeans_alpha, df = test$parameter, lower.tail = TRUE) ] <- NA
return(y)
}
}
p <- ggplot(data.frame(x = c(qt(0.999, df = test$parameter, lower.tail = FALSE), qt(0.999, df = test$parameter, lower.tail = TRUE))), aes(x = x)) +
stat_function( fun = dt, fill="gray90", args = list(df = test$parameter)) +
stat_function( fun = funcShaded, geom = "area", fill = "sky blue", alpha = 0.8) +
theme_minimal() +
geom_vline(xintercept = test$statistic, color = "steelblue") +
geom_text(aes(x = test$statistic, label = paste0("검정 통계량 = ", round(test$statistic, 3)), y = 0.2), colour = "steelblue", angle = 90, vjust = 1.3, text = element_text(size = 11)) +
ggtitle(paste0("t-분포", " t(", round(test$parameter, 3), ")")) +
theme(plot.title = element_text(face = "bold", hjust = 0.5)) +
ylab("밀도") +
xlab("x")
p
} else if ( input$twomeans_popsd == FALSE & input$twomeans_var.equal == FALSE) {
dat1 <- as.numeric(unlist(strsplit(input$twomeans_sample1, ",")))
dat2 <- as.numeric(unlist(strsplit(input$twomeans_sample2, ",")))
test <- t.test(x = dat1, y = dat2, mu = input$twomeans_h0, alternative = input$twomeans_alternative, conf.level = 1 - input$twomeans_alpha, paired = FALSE, var.equal = FALSE)
if (input$twomeans_alternative == "two.sided") {
funcShaded <- function(x) {
y <- dt(x, df = test$parameter)
y[x < qt(input$twomeans_alpha / 2, df = test$parameter, lower.tail = FALSE) | x > qt(input$twomeans_alpha / 2, df = test$parameter, lower.tail = TRUE) ] <- NA
return(y)
}
} else if (input$twomeans_alternative == "greater") {
funcShaded <- function(x) {
y <- dt(x, df = test$parameter)
y[x < qt(input$twomeans_alpha, df = test$parameter, lower.tail = FALSE) ] <- NA
return(y)
}
} else if (input$twomeans_alternative == "less") {
funcShaded <- function(x) {
y <- dt(x, df = test$parameter)
y[x > qt(input$twomeans_alpha, df = test$parameter, lower.tail = TRUE) ] <- NA
return(y)
}
}
p <- ggplot(data.frame(x = c(qt(0.999, df = test$parameter, lower.tail = FALSE), qt(0.999, df = test$parameter, lower.tail = TRUE))), aes(x = x)) +
stat_function( fun = dt, fill="gray90", args = list(df = test$parameter)) +
stat_function( fun = funcShaded, geom = "area", fill = "sky blue", alpha = 0.8) +
theme_minimal() +
geom_vline(xintercept = test$statistic, color = "steelblue") +
geom_text(aes(x = test$statistic, label = paste0("검정 통계량Here is the rest of the code with the bug fixed:
= ", round(test$statistic, 3)), y = 0.2), colour = "steelblue", angle = 90, vjust = 1.3, text = element_text(size = 11)) +
ggtitle(paste0("t-분포", " t(", round(test$parameter, 3), ")")) +
theme(plot.title = element_text(face = "bold", hjust = 0.5)) +
ylab("밀도") +
xlab("x")
p
} else if ( input$twomeans_popsd == TRUE ) {
dat1 <- as.numeric(unlist(strsplit(input$twomeans_sample1, ",")))
dat2 <- as.numeric(unlist(strsplit(input$twomeans_sample2, ",")))
test <- t.test3(x = dat1, y = dat2,
V1 = input$twomeans_sigma21, V2 = input$twomeans_sigma22,
m0 = input$twomeans_h0, alpha = input$twomeans_alpha, alternative = input$twomeans_alternative)
if (input$twomeans_alternative == "two.sided") {
funcShaded <- function(x) {
y <- dnorm(x, mean = 0, sd = 1)
y[x < qnorm(input$twomeans_alpha / 2, mean = 0, sd = 1, lower.tail = FALSE) | x > qnorm(input$twomeans_alpha / 2, mean = 0, sd = 1, lower.tail = TRUE) ] <- NA
return(y)
}
} else if (input$twomeans_alternative == "greater") {
funcShaded <- function(x) {
y <- dnorm(x, mean = 0, sd = 1)
y[x < qnorm(input$twomeans_alpha, mean = 0, sd = 1, lower.tail = FALSE) ] <- NA
return(y)
}
} else if (input$twomeans_alternative == "less") {
funcShaded <- function(x) {
y <- dnorm(x, mean = 0, sd = 1)
y[x > qnorm(input$twomeans_alpha, mean = 0, sd = 1, lower.tail = TRUE) ] <- NA
return(y)
}
}
p <- ggplot(data.frame(x = c(qnorm(0.999, mean = 0, sd = 1, lower.tail = FALSE), qnorm(0.999, mean = 0, sd = 1, lower.tail = TRUE))), aes(x = x)) +
stat_function( fun = dnorm, fill="gray90", args = list(mean = 0, sd = 1)) +
stat_function( fun = funcShaded, geom = "area", fill = "sky blue", alpha = 0.8) +
theme_minimal() +
geom_vline(xintercept = test$statistic, color = "steelblue") +
geom_text(aes(x = test$statistic, label = paste0("검정 통계량 = ", round(test$statistic, 3)), y = 0.2), colour = "steelblue", angle = 90, vjust = 1.3, text = element_text(size = 11)) +
ggtitle(paste0("정규 분포 N(0,1)")) +
theme(plot.title = element_text(face = "bold", hjust = 0.5)) +
ylab("밀도") +
xlab("x")
p
}
})
output$table_twomean <- render_gt({
dat1 <- as.numeric(unlist(strsplit(input$twomeans_sample1, ",")))
dat2 <- as.numeric(unlist(strsplit(input$twomeans_sample2, ",")))
tibble(변수1 = dat1, 변수2 = dat2) %>%
gt()
})
})
}
ui <- fluidPage(
titlePanel("2표본 평균 가설 검정"),
two_means_UI("twomeans")
)
server <- function(input, output, session) {
two_means_server("twomeans")
}
shinyApp(ui, server)
2 코딩
라이센스
CC BY-SA-NC & GPL-3