% !Rnw root = EDA_Report_KR.Rnw

<<enrironment, echo=FALSE, warning=FALSE, message=FALSE>>=
options(warn = -1)

library(dplyr)
library(ggplot2)
library(gridExtra)
library(knitr)
library(kableExtra)

opts_chunk$set(fig.path = paste(tempdir(), 'figure/minimal-', sep = "/"), fig.align = 'center',
               fig.show = 'hold', warning = FALSE, message = FALSE)
options(replace.assign = TRUE, width = 90)

dist_numeric <- function(df, target, predictor) {
  descr <- df %>%
    target_by(target) %>%
    relate(predictor)

  vars <- unlist(descr[, 2])

  descr <- descr %>%
    select(-c(1:2)) %>%
    t

  colnames(descr) <- vars

  descr <- descr[, rev(seq(NCOL(descr)))]

  rnames <- c("n", "NA", "mean", "sd", "se(mean)", "IQR",
              "skewness", "kurtosis")
  rnames <- c(rnames, paste0(c(0, 1, 5, 10, 20, 25, 30, 40, 50, 60, 70,
                               75, 80, 90, 95, 99, 100), "%"))
  row.names(descr) <- rnames

  as.data.frame(descr)
}

change_under <- function(x) {
  gsub("_", "\\\\_", x)
}

edaData <- as.data.frame(get("edaData", .dlookrEnv))
targetVariable <- get("targetVariable", .dlookrEnv)

if (length(targetVariable) == 0) targetVariable <- NULL

options(knitr.table.format = "latex")
@

<<check_variables, echo=FALSE>>=
idx.numeric <- find_class(edaData, type = "numerical")
idx.factor <- find_class(edaData, type = "categorical")
nm.numeric <- find_class(edaData, type = "numerical", index = FALSE)
nm.factor <- find_class(edaData, type = "categorical", index = FALSE)

if (!is.null(targetVariable)) {
  # remove target variable from variable index
  idx.numeric <- idx.numeric[nm.numeric != targetVariable]
  idx.factor <- idx.factor[nm.factor != targetVariable]

  factor_flag <- class(pull(edaData, targetVariable))[1] %in% c("factor", "ordered")
  numeric_flag <- class(pull(edaData, targetVariable))[1] %in% c("integer", "numeric")

  target <- if (!factor_flag & numeric_flag)
    factor(pull(edaData, targetVariable)) else
      pull(edaData, targetVariable)
} else { # fix error while performing eda_web_report() #83
  factor_flag <- FALSE
  numeric_flag <- FALSE
}

# if all elements of a numerical variable are NA,
# remove from correlation coefficient calculation
idx.numeric <- idx.numeric[apply(as.data.frame(edaData[, idx.numeric]), 2,
                                 function(x) !all(is.na(x)))]

# if all elements of the numerical variable are the same value,
# remove from the correlation coefficient calculation
idx.numeric <- idx.numeric[apply(as.data.frame(edaData[, idx.numeric]), 2,
                                 function(x) diff(range(x, na.rm = TRUE)) > 0)]

N <- NROW(edaData)
@

\chapter{개요}
EDA(Exploratory Data Analysis) 보고서는 data.frame 및 data.frame을 상속받은 객체에 대한 탐색적 데이터 분석 정보를 제공한다.

\section{데이터셋 정보}
EDA 보고서를 생성한 데이터셋은 '\Sexpr{class(edaData)[1]}' 객체다. 이 데이터 객체는 \Sexpr{format(NROW(edaData), big.mark = ",")}개의 관측치와 \Sexpr{NCOL(edaData)}개의 변수로 구성되었다.

\section{변수들의 정보}
<<info_variables, echo=FALSE, results='asis'>>=
cap <- "변수들의 정보 목록"

vars <- edaData %>%
  diagnose() %>% 
  mutate(missing_percent = round(missing_percent, 2),
         unique_rate = round(unique_rate, 3))

knitr::kable(vars, caption = cap, booktabs = TRUE, longtable = TRUE) %>%
  kable_styling(latex_options = c("striped", "hold_position")) %>%
  kable_styling(latex_options = c("repeat_header")) %>% 
  cat()

target_nm <- if (is.null(targetVariable)) "NULL" else targetVariable
target_type <- if (is.null(targetVariable))
  "NULL(You did not specify a target variable)" else
  class(pull(edaData, targetVariable))[1]
@

데이터셋의 목적변수(target variable) 이름은 '\Sexpr{change_under(target_nm)}', 변수의 데이터 유형(data type)은 \Sexpr{target_type}이다.

\section{EDA 보고서에 대해}
EDA 보고서는 EDA 프로세스를 지원하는 정보 및 시각화 결과를 제공한다. 특히 목적변수와 나머지 변수(predictor, 예측자 혹은 독립변수)의 관계를 이해하기 위한 다양한 정보를 제공한다.

\chapter{단변량 분석}
\section{기술통계(Descriptive Statistics)}

<<describe_univariate, echo=FALSE, comment="", results='asis'>>=
x <- Hmisc:::describe.data.frame(edaData)
Hmisc::latex(x, file = "")
@

\clearpage

\section{정규성 검정}
\subsection{통계량과 시각화}
<<normality, echo=FALSE, results='asis'>>=
if (length(idx.numeric) == 0) {
  cat("\n\n수치형 변수가 없습니다.\n\n")
} else {
  for (i in idx.numeric) {
    cap <- change_under(names(edaData)[i])

    cat("\n")
    cat("\\subsubsection{", cap, "}\n")

    cat("\\noindent * 검정 방법 : Shapiro-Wilk normality test\n\n")

    x <- pull(edaData, i) %>%
      .[!is.na(.)]
 
    if (length(x) == 0) {
      cat("모든 관측치가 결측치입니다.\n\n")
      cat("\\clearpage")
      next
    }
 
    if (length(x) > 5000) {
      x <- sample(x, size = 5000, replace = TRUE)
    }
 
    if(length(x) < 3L || length(x) > 5000L) {
      cat("검정을 위한 샘플의 크기는 3 이상 5000 이하여야 합니다.\n\n")
      cat("\\clearpage")
      next
    }
 
    if(diff(range(x, na.rm = TRUE)) == 0) {
      cat("모든 관측치가 동일한 값입니다.\n\n")
      cat("\\clearpage")
      next
    }

    y <- shapiro.test(x)

    cat(sprintf("\\noindent - statistic : %s,  p-value : %G\\\\\n",
                round(y$statistic, 5),  y$p.value))

    if (is.factor(x)) x <- as.numeric(x)
    
    if (sum(x < 0, na.rm = TRUE) > 0) { 
      type <- c("원데이터", "log+a 변환", "Box-Cox 변환")
  
      skew <- c(skewness(x, na.rm = TRUE),
                skewness(get_transform(x, "log+a"), na.rm = TRUE),
                skewness(get_transform(x, "Box-Cox"), na.rm = TRUE))
  
      kurt <- c(kurtosis(x, na.rm = TRUE),
                kurtosis(get_transform(x, "log+a"), na.rm = TRUE),
                kurtosis(get_transform(x, "Box-Cox"), na.rm = TRUE))          
    } else {
      if (any(x == 0, na.rm = TRUE)) {
        type <- c("원데이터", "log+1 변환", "sqrt 변환")
        
        skew <- c(skewness(x, na.rm = TRUE),
                  skewness(get_transform(x, "log+1"), na.rm = TRUE),
                  skewness(sqrt(x), na.rm = TRUE))
        
        kurt <- c(kurtosis(x, na.rm = TRUE),
                  kurtosis(get_transform(x, "log+1"), na.rm = TRUE),
                  kurtosis(sqrt(x), na.rm = TRUE))         
      } else {
        type <- c("원데이터", "log 변환", "sqrt 변환")
        
        skew <- c(skewness(x, na.rm = TRUE),
                  skewness(log(x), na.rm = TRUE),
                  skewness(sqrt(x), na.rm = TRUE))
        
        kurt <- c(kurtosis(x, na.rm = TRUE),
                  kurtosis(log(x), na.rm = TRUE),
                  kurtosis(sqrt(x), na.rm = TRUE)) 
      } 
    }

    stats <- data.frame(type = type, skewness = skew, kurtosis = kurt)

    tab_cap <- paste("skewness and kurtosis :", cap)

    cat("\\\\")

    kable(stats, digits = 4, caption = tab_cap, 
          label = paste0("numeric_variables", i),
          booktabs = TRUE, escape = FALSE) %>%
      kable_styling(latex_options = c("striped", "hold_position")) %>%
      cat()

    cat("\\\\")
    cat("\n")

    if (N >= 5000) {
      png(filename = sprintf("./figure/norm%s.png", i), width = 600, height = 400)
    } else {
      cairo_pdf(filename = sprintf("./figure/norm%s.pdf", i), width = 6, height = 4, 
        family = "NanumGothic")
    }

    x <- data.frame(x)
    
    if (sum(x < 0, na.rm = TRUE) > 0) {
      plot_normality(x, x, left = "log+a", right = "Box-Cox")
    } else {
      if (any(x == 0, na.rm = TRUE)) 
        plot_normality(x, x, left = "log+1", right = "sqrt")
      else
        plot_normality(x, x)
    }
    dev.off()

    cap <- change_under(names(edaData)[i])

    cat("\\begin{figure}[!ht]\n")
    cat("\\centering\n")

    if (N >= 5000) {
      cat(sprintf("\\includegraphics[width=0.8\\textwidth]{figure/norm%s.png}\n", i))
    } else {
      cat(sprintf("\\includegraphics[width=0.8\\textwidth]{figure/norm%s.pdf}\n", i))
    } 

    cat(sprintf("\\caption{%s}\n", cap))
    cat("\\end{figure}\n")

    cat("\\clearpage")
  }
}
@

\chapter{변수들간의 관계}
\section{상관계수}
\subsection{변수조합별 상관계수}
<<correlations, echo=FALSE, results='asis'>>=
if (length(idx.numeric) > 2) {
  eps <- 0.5

  cors <- edaData %>%
    correlate %>%
    filter(abs(coef_corr) >= eps) %>%
    filter(as.integer(var1) > as.integer(var2)) %>%
    arrange(desc(abs(coef_corr)))

  if (NROW(cors) > 0) {
    names(cors) <- c("기준변수", "대응변수", "상관계수")

    cap <- "변수별 상관계수 목록 (0.5 이상)"

    kable(cors, booktabs = TRUE, caption = cap,
          digits = 3, longtable = TRUE) %>%
      kable_styling(latex_options = c("striped", "scale_down")) %>%
      kable_styling(latex_options = c("hold_position")) %>%
      kable_styling(latex_options = c("repeat_header")) %>%
      cat()
  } else {
    cat("\n\n상관계수의 절대치가 0.5 이상인 수치형 변수의 조합이 없습니다.\n\n")
  }
} else {
  cat("\n\n수치형 변수의 개수가 2보다 적습니다.\n\n")
}
@

\subsection{변수조합별 상관계수 시각화}
<<plot_correlations, echo=FALSE, results='asis'>>=
if (length(idx.numeric) > 2) {
  cairo_pdf(filename = sprintf("./figure/correlation.pdf", i), width = 6, height = 6)
  edaData %>%
    correlate() %>% 
    plot()
  dev.off()

  cap <- "상관행렬 플롯"

  cat("\\begin{figure}[!ht]\n")
  cat("\\centering\n")
  cat(sprintf("\\includegraphics[width=0.99\\textwidth]{figure/correlation.pdf}\n", i))
  cat(sprintf("\\caption{%s}\n", cap))
  cat("\\end{figure}\n")  
} else {
  cat("수치형 변수의 개수가 2보다 적습니다.\n\n")
} 
@

\chapter{목적변수 기반의 분석}
\section{목적변수 그룹별 기술통계}
\subsection{목적변수 대응 수치형 변수}

<<create_target_by, echo=FALSE, results='asis'>>=
if (!is.null(targetVariable)) {
  target_by_obj <- target_by(edaData, all_of(targetVariable))
}  
@

<<numeric_variables, echo=FALSE, results='asis', message=FALSE, warning=FALSE>>=
if (!is.null(targetVariable)) {
  if (factor_flag) {
    if (length(idx.numeric) == 0) {
      cat("수치형 변수가 없습니다.\n\n")
    } else {
      for (i in idx.numeric) {
        cat("\n")
        cat("\\subsubsection{", change_under(names(edaData)[i]), "}\n")

        cat("\n\\begin{center}\n")

        z <- dist_numeric(edaData, targetVariable, names(edaData)[i])

        ncols <- NCOL(z) 
        rcnt <- round(ncols / 3)

        cap <- change_under(names(edaData)[i])

        kable(z, digits = 2, caption = cap, booktabs = TRUE,
              label = paste0("numeric_variables", i),
              format.args = list(big.mark = ",")) %>%
          kable_styling(latex_options = c("striped", "hold_position")) %>%
          cat()

        if (N >= 5000) {
          png(filename = sprintf("./figure/%s.png", i), width = 700, height = 500)
        } else {
          cairo_pdf(filename = sprintf("./figure/%s.pdf", i), width = 8, height = 6, 
                    family = "NanumGothic")
        }

        plot_outlier(target_by_obj, names(edaData)[i])
        dev.off()

        cap <- change_under(names(edaData)[i])

        cat("\\begin{figure}[!ht]\n")
        cat("\\centering\n")

        if (N >= 5000) {
          cat(sprintf("\\includegraphics[width=0.9\\textwidth]{figure/%s.png}\n", i))
        } else {
          cat(sprintf("\\includegraphics[width=0.9\\textwidth]{figure/%s.pdf}\n", i))
        } 

        cat(sprintf("\\caption{%s}\n", cap))
        cat("\\end{figure}\n")

        cat("\n\\end{center}\n")
        cat("\\clearpage")
      }
    }
  } else if (numeric_flag) {
    if (length(idx.numeric) == 0) {
        cat("수치형 변수가 없습니다.\n\n")
    } else {
      targetby <- target_by(edaData, targetVariable)
      for (i in idx.numeric) {
        cat("\n")
        cat("\\subsubsection{", change_under(names(edaData)[i]), "}\n")

        num_num <- relate(targetby, names(edaData)[i])

        tab <- summary(num_num)$coefficients
        colnames(tab)[4] <- c("Pr($\\textgreater \\mid t \\mid$)")
        row.names(tab) <- change_under(row.names(tab))

        rsq <- summary(num_num)$r.squared
        adj <- summary(num_num)$adj.r.squared
        fstat <- summary(num_num)$fstatistic
        df <- summary(num_num)$df
        rse <- summary(num_num)$sigma

        cat("\n\\textbf{1. 단순 선형모형 정보}\n\\\\")
        cat("\\\\")
        cat(sprintf("\t Residual standard error: %s on %s degrees of freedom\n\\\\",
                round(rse),  df[2]))
        cat(sprintf("\t Multiple R-squared:  %s,	Adjusted R-squared:  %s\n\\\\",
                round(rsq, 5), round(adj, 5)))
        cat(sprintf("\t F-statistic: %s on %s and %s DF,  p-value: %s\n",
                round(fstat["value"]),  fstat["numdf"], fstat["dendf"],
                round(tab[2, 4], 7)))
        cat("\n")

        cap <- sprintf("단순 선형모형의 계수 : %s", names(edaData)[i])
        cap <- paste(unlist(strsplit(cap, "_")), collapse = "\\_")

        kable(tab, digits = 2, caption = cap, 
              label = paste0("numeric_variables", i),
              booktabs = TRUE, escape = FALSE) %>%
          kable_styling(latex_options = c("striped", "hold_position")) %>%
          cat()

        png(filename = sprintf("./figure/linear%s.png", i), width = 800, height = 400)
        suppressMessages(plot(num_num))
        dev.off()

        cap <- change_under(names(edaData)[i])

        cat("\n\\noindent\\textbf{2. 시각화 - 산점도}\n")

        cat("\n\\begin{center}\n")
        cat("\\begin{figure}[!ht]\n")
        cat("\\centering\n")
        cat(sprintf("\\includegraphics[width=1.0\\textwidth]{figure/linear%s.png}\n", i))
        cat(sprintf("\\caption{%s}\n", cap))
        cat("\\end{figure}\n")

        cat("\n\\end{center}\n")
        cat("\\clearpage")
      }
    }
  }
} else {
  cat("목적변수를 지정하지 않았습니다.\n\n")
}
@

\subsection{목적변수 대응 범주형 변수}

<<category_variables, echo=FALSE, results='asis'>>=
if (!is.null(targetVariable)) {
  if (factor_flag) {
    if (length(idx.factor) == 0) {
      cat("범주형 변수가 없습니다.\n\n")
    } else {
      for (i in idx.factor) {
        if (sum(!is.na(edaData[, i])) == 0) next

        cat("\n")
        cat("\\subsubsection{", change_under(names(edaData)[i]), "}\n")

        cat("\n\\begin{center}\n")

        tab <- edaData %>%
          target_by(targetVariable) %>%
          relate(names(edaData)[i]) %>%
          t()

        freq <- addmargins(tab)
        idx.na <- which(is.na(rownames(freq)))
        rownames(freq)[idx.na] <- "NA"

        ncols <- NCOL(freq) - 1
        rcnt <- round(ncols / 3)

        ratio <- sweep(freq, 2, c(apply(tab, 2, sum), sum(tab)), "/") * 100
        idx.na <- which(is.na(rownames(ratio)))
        rownames(ratio)[idx.na] <- "NA"

        kable(freq, booktabs = TRUE,
              label = paste0("category_variables", i),
              format.args = list(big.mark = ",")) %>%
          kable_styling(font_size = 8, latex_options = "striped") %>%
          row_spec(NROW(ratio), bold = TRUE) %>%
          cat()

        if(ncols > 2) {
          cat("\n")
          cat("\n\\vspace{2em}")
        }

        kable(ratio, booktabs = TRUE, digits = 2,
              label = paste0("category_variables_2", i),
              format.args = list(big.mark = ",")) %>%
          kable_styling(font_size = 8, latex_options = "striped") %>%
          row_spec(NROW(ratio), bold = TRUE) %>%
          cat()

        mosaics <- relate(target_by_obj, names(edaData)[i])

        cairo_pdf(filename = sprintf("./figure/%s.pdf", i), width = 8, height = 6, family = "NanumGothic")
        print(plot(mosaics))
        dev.off()

        cat("\n\\vspace{1em}\n")
        cap <- change_under(names(edaData)[i])

        cat("\\begin{figure}[!ht]\n")
        cat("\\centering\n")
        cat(sprintf("\\includegraphics[width=0.9\\textwidth]{figure/%s.pdf}\n", i))
        cat(sprintf("\\caption{%s}\n", cap))
        cat("\\end{figure}\n")

        cat("\n\\end{center}\n")
        cat("\\clearpage")
      }
    }
  } else if (numeric_flag) {
    if (length(idx.factor) == 0) {
        cat("범주형 변수가 없습니다.\n\n")
    } else {
      targetby <- target_by(edaData, targetVariable)
      for (i in idx.factor) {
        cat("\n")
        cat("\\subsubsection{", change_under(names(edaData)[i]), "}\n")

        num_cat <- relate(targetby, names(edaData)[i])

        tab_aov <- data.frame(anova(num_cat))
        colnames(tab_aov) <- c("Df", "Sum Sq", "Mean Sq", "F value",
                               "Pr($\\textgreater \\mid F \\mid$)")

        cat("\n\\textbf{1. 분산분석(ANOVA)}\n\n")

        cap <- sprintf("분산분석표 : %s", names(edaData)[i])
        cap <- paste(unlist(strsplit(cap, "_")), collapse = "\\_")

        row.names(tab_aov) <- change_under(row.names(tab_aov))

        knitr::kable(tab_aov, digits = 2, caption = cap,
                     label = paste0("category_variables_3", i),
                     booktabs = TRUE, escape = FALSE) %>%
          kable_styling(latex_options = c("striped", "hold_position")) %>%
          cat()

        cat("\n")

        tab <- summary(num_cat)$coefficients
        colnames(tab)[4] <- c("Pr($\\textgreater \\mid t \\mid$)")

        rsq <- summary(num_cat)$r.squared
        adj <- summary(num_cat)$adj.r.squared
        fstat <- summary(num_cat)$fstatistic
        df <- summary(num_cat)$df
        rse <- summary(num_cat)$sigma

        cat("\\noindent\\textbf{2. 단순 선형모형 정보}\n\\\\")
        cat("\\\\")
        cat(sprintf("\t Residual standard error: %s on %s degrees of freedom\n\\\\",
                round(rse),  df[2]))
        cat(sprintf("\t Multiple R-squared:  %s,	Adjusted R-squared:  %s\n\\\\",
                round(rsq, 5), round(adj, 5)))
        cat(sprintf("\t F-statistic: %s on %s and %s DF,  p-value: %s\n",
                round(fstat["value"]),  fstat["numdf"], fstat["dendf"],
                round(tab[2, 4], 7)))
        cat("\n")

        cap <- sprintf("단순 선형모형의 계수 : %s", names(edaData)[i])
        cap <- paste(unlist(strsplit(cap, "_")), collapse = "\\_")

        row.names(tab) <- change_under(row.names(tab))
        
        knitr::kable(tab, digits = 2, caption = cap,
                     label = paste0("category_variables_4", i),
                     booktabs = TRUE, escape = FALSE) %>%
          kable_styling(latex_options = c("striped", "hold_position")) %>%
          cat()

        if (N >= 5000) {
          png(filename = sprintf("./figure/%s.png", i), width = 600, height = 400)
        } else {
          cairo_pdf(filename = sprintf("./figure/%s.pdf", i), width = 6, height = 4,
                    family = "NanumGothic")
        }

        print(plot(num_cat))
        dev.off()

        cat("\n\\vspace{1em}\n")
        cap <- change_under(names(edaData)[i])

        cat("\n\\begin{center}\n")
        cat("\\begin{figure}[!ht]\n")
        cat("\\centering\n")

        if (N >= 5000) {
          cat(sprintf("\\includegraphics[width=0.8\\textwidth]{figure/%s.png}\n", i))
        } else {
          cat(sprintf("\\includegraphics[width=0.8\\textwidth]{figure/%s.pdf}\n", i))
        } 

        cat(sprintf("\\caption{%s}\n", cap))
        cat("\\end{figure}\n")

        cat("\n\\end{center}\n")
        cat("\\clearpage")
      }
    }
  }
} else {
  cat("목적변수를 지정하지 않았습니다.\n\n")
}
@

\section{목적변수 그룹별 변수들간의 관계}
\subsection{목적변수 대응 상관계수}
<<group_correlations, echo=FALSE, results='asis'>>=
if (!is.null(targetVariable)) {
  if (factor_flag) {
    if (length(idx.numeric) > 2) {
      eps <- 0.5

      idx <- which(names(edaData) %in% targetVariable)
      names(edaData)[idx] <- "targetVariable"

      cors <- edaData %>%
        group_by(targetVariable) %>%
        correlate %>%
        filter(abs(coef_corr) >= eps) %>%
        filter(as.integer(var1) > as.integer(var2)) %>%
        arrange(targetVariable, desc(abs(coef_corr)))

      if (NROW(cors) > 0) {
        names(cors) <- c(targetVariable, "기준변수", "대응변수", "상관계수")

        cap <- "변수별 상관계수 목록 (0.5 이상)"

        kable(cors, booktabs = TRUE,
              caption = cap, digits = 3, longtable = TRUE) %>%
          kable_styling(latex_options = c("striped", "scale_down")) %>%
          kable_styling(latex_options = c("hold_position")) %>%
          kable_styling(latex_options = c("repeat_header")) %>%
          cat()
      } else {
        cat("상관계수의 절대치가 0.5 이상인 수치형 변수의 조합이 없습니다.\n\n")
      }
    } else {
      cat("수치형 변수의 개수가 2보다 적습니다.\n\n")
    }
  } else if (numeric_flag) {
    cat("목적변수가 수치형 변수인 경우에는 지원하지 않습니다.\n\n")
  }
} else {
  cat("목적변수를 지정하지 않았습니다.\n\n")
}
@

\subsection{목적변수 대응 상관계수 시각화}
<<plot_group_correlations, echo=FALSE, results='asis'>>=
if (!is.null(targetVariable)) {
  if (factor_flag) {
    if (length(idx.numeric) > 2) {
      level_name <- levels(edaData$targetVariable)

      for (i in seq(level_name)) {
        cat(sprintf("\\noindent - 목적변수의 조건 (%s == %s)\n\n", 
          change_under(targetVariable), level_name[i]))

        fname <- paste("./figure/myfile_", i, ".pdf", sep = "")
        cairo_pdf(filename = fname, width = 6, height = 6, family = "NanumGothic")
        edaData %>%
          filter(targetVariable %in% level_name[i]) %>%
          correlate() %>% 
          plot()
        dev.off()
        
        cap <- sprintf("상관행렬 플롯 (%s == %s)", 
          change_under(targetVariable), level_name[i])

        cat("\\begin{figure}[!ht]\n")
        cat("\\begin{center}\n")
        cat("\\includegraphics{", fname, "}\n", sep = "")
        cat("\\caption{", cap, "}\n", sep = "")
        cat("\\end{center}\n")
        cat("\\end{figure}")
      }
    } else {
      cat("수치형 변수의 개수가 2보다 적습니다.\n\n")
    }
  } else if (numeric_flag) {
    cat("목적변수가 수치형 변수인 경우에는 지원하지 않습니다.\n\n")
  }
} else {
  cat("목적변수를 지정하지 않았습니다.\n\n")
}
@

<<option_undo, echo=FALSE>>=
options(warn = 0)
@

