こんにちは、usagi-sanです。
R言語で統計解析を行う際、検定結果がsummary(ans)の中にリストとして格納されているため、検定結果の操作が難しいと思う方が多いと思います。
また結果の表をcsvやexcelに出力できても、有意な変数がどれなのか分からない場合がほとんどです。
今回は、統計検定の結果についてのデータフレームを自動で色塗りする関数を作ってみました。
今回紹介する関数は次の記事のパッケージをインストールすることで利用可能です。また、スクリプトファイルをダウンロードしたい方は、この記事の下のダウンロードリンクからダウンロードしてください。
R言語 自作パッケージ UsagiSan
こんにちは、usagi-sanです。 R言語の自作パッケージを紹介します。 統計解析のアルバイトをしている中、暇な時間を見つけて自分でパッケージを作ってみました。 Rのパッケージには、統計解析用のパッ ...
続きを見る
自由なメモ
2020-7-28に関数を更新しました。関数のエラーの修正と有意水準の指定、また色塗りの実行時間を考慮し横のずれを修正する機能を無くすオプションも付けました。
2020-9-18にp値に対応する列名を任意に選択できるようにしました。また、各種不具合を修正しました。
自作色塗り関数の紹介
csvやexcelなどの検定結果のファイルをread.tableやread.csvでデータフレームに格納したあと、そのデータフレームを自動で色塗りするプログラムの概要を紹介します。
下のような検定結果のヘッダーと有意な説明変数を自動で色塗りするプログラムです。
色塗り後は次のようになります。
例では、ロジスティック回帰の結果について色塗りをしています。
また、もちろん任意のデータの重回帰分析、ロジスティック回帰、Cox回帰などの様々な検定結果にも適用できます。
また上の画像のように複数の検定結果を一度に色塗りすることも可能です。
さらに上で示しているように、解析結果が横にずれていたり、異なる検定の解析結果を一度に色塗りしたい場合などでも有効です。
関数の使いかた
次に、関数の使いかたを説明をします。
関数のプログラミングコードとともに説明します。
excelColor
次のプログラミングコードは検定結果の色塗りに用います。
ヘッダーと有意水準以下の変数を色塗りしてくれます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | excelColor <- function(dataName, fileName, level = 0.05, pValue = c("Pr(>|z|)", "Pr(>|t|)", "p-value"), significanceColor = "#FFFF00", headerColor = "#92D050", fontSize = 11, fontName = "Yu Gothic", fontColor = "#000000", intercept = FALSE, adj = TRUE, fileEncoding = "CP932") { options(warn = -1) if (is.na(dataName)) { stop("There is no data-name") } options(warn = 0) if (is.na(fileName)) { stop("There is no file-name") } if (!(is.character(fileName))) { stop("The file-name must be character") } data <- utils::read.table(paste0(dataName, ".csv"), fill = TRUE, header = FALSE, sep = ",", blank.lines.skip = FALSE, fileEncoding = fileEncoding) wb <- openxlsx::createWorkbook() openxlsx::addWorksheet(wb, "Sheet 1") st <- openxlsx::createStyle(fontName = fontName, fontSize = fontSize) openxlsx::addStyle(wb, "Sheet 1", style = st, cols = 1:2, rows = 1:2) openxlsx::writeData(wb, sheet = "Sheet 1", x = data, colNames = F, withFilter = F) openxlsx::modifyBaseFont(wb, fontSize = fontSize, fontColour = fontColor, fontName = fontName) init <- initialize(data, pValue, mode = "test") tmp <- init$tmp tmp2 <- init$tmp2 green_header <- init$gr_header footer <- init$footer col_count <- NULL col_intercept <- NULL table_rightLim <- NULL options(warn = -1) if (length(tmp) == 0) { stop("There is no such pvalue' colname") } options(warn = 0) if (adj == TRUE) { cols <- getPotision_sigVar_Intercpt_rLim(green_header, data, pValue, tmp2, col_count, col_intercept, table_rightLim) col_count <- cols$count col_intercept <- cols$intercept table_rightLim <- cols$rightLim #setStyle for headers for (i in seq_len(length(green_header))) { st <- openxlsx::createStyle(fontName = fontName, fontSize = fontSize, fgFill = headerColor) openxlsx::addStyle(wb, "Sheet 1", style = st, cols = col_intercept[i]:table_rightLim[i], rows = green_header[i]) } factor_list <- list(NULL) factor_list <- mkFactorList(green_header, footer, factor_list, 1, data) factor_row <- list(NULL) for (i in seq_len(length(factor_list))) { bar <- factor_list[[i]] factor_row[[i]] <- bar[as.numeric(data[factor_list[[i]], col_count[i]]) < level] } #removing NA factor_row <- removeNA(factor_row, adj) #write data writeDatas(factor_list, data, wb) #setStyle for significant variables st <- openxlsx::createStyle(fontName = fontName, fontSize = fontSize, fgFill = significanceColor) for (i in seq_len(length(factor_list))) { openxlsx::addStyle(wb, "Sheet 1", style = st, cols = col_count[i], rows = factor_row[[i]]) } if (intercept == TRUE) { for (i in seq_len(length(factor_list))) { openxlsx::addStyle(wb, "Sheet 1", style = st, cols = col_intercept[i], rows = factor_row[[i]]) } }else { for (i in seq_len(length(factor_list))) { openxlsx::addStyle(wb, "Sheet 1", style = st, cols = col_intercept[i], rows = setdiff(factor_row[[i]], green_header[i] + 1)) } } }else { st <- openxlsx::createStyle(fontName = fontName, fontSize = fontSize, fgFill = headerColor) for (k in seq_len(ncol(data))) { for (l in seq_len(length(pValue))) { if (tmp2[1, k] == pValue[l]) { col_count[1] <- k } } openxlsx::addStyle(wb, "Sheet 1", style = st, cols = k, rows = green_header) } options(warn = -1) factor_row <- as.numeric(rownames(data[replace(as.numeric(data[, col_count[1]]) < level, is.na(as.numeric(data[, col_count[1]]) < level), FALSE), ])) options(warn = 0) #removing NA factor_row <- removeNA(factor_row, adj) factor_list <- list(NULL) factor_list <- mkFactorList(green_header, footer, factor_list, 1, data) #write data writeDatas(factor_list, data, wb) st <- openxlsx::createStyle(fontName = fontName, fontSize = fontSize, fgFill = significanceColor) openxlsx::addStyle(wb, "Sheet 1", style = st, cols = col_count[1], rows = factor_row) if (intercept == TRUE) { openxlsx::addStyle(wb, "Sheet 1", style = st, cols = 1, rows = factor_row) }else { openxlsx::addStyle(wb, "Sheet 1", style = st, cols = 1, rows = setdiff(factor_row, green_header[i] + 1)) } } openxlsx::saveWorkbook(wb, paste0(fileName, ".xlsx"), overwrite = TRUE) } |
関数excelColorの引数については以下の表にまとめました。上の画像のように検定結果を色塗りしたい場合はexcelColorを用います。
dataName | 統計解析の結果が含まれているファイル名(csvのファイルのみ) | fontSize | フォントのサイズ |
fileName | 色塗り後の解析結果のファイル名 | fontName | フォント名 |
significanceColor | 有意な変数の色 | fontColor | フォントの色 |
excelHeadColorColor | 解析結果のヘッダーの色 | intercept | 切片パラメータの色を塗るかどうか(TUREの場合、色が塗られます) |
leve | 色塗りをする有意水準の基準(level = 0.1だと0.1以下の変数が色塗りの対象となります。) | adj | TRUEの場合、検定結果の横のずれを修正する機能をもつ |
pValue | 塗りたいp値の列の名前。初期値として、c("Pr(>|z|)", "Pr(>|t|)", "p-value")のベクトルをもつ。 | fileEncoding | ファイルエンコーディング。初期値は"CP932"である。 |
excelHeadColor
2つ目の関数として、ヘッダーのみを色塗りする関数excelHeadColorを紹介します。
こちらは検定結果ではなく、簡単な集計表のヘッダーの色塗りに用います。
次のプログラミングコードが関数excelHeadColorとなります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | excelHeadColor <- function(dataName, fileName, header, headerColor = "#92D050", fontSize = 11, fontName = "Yu Gothic", fontColor = "#000000", adj = TRUE, fileEncoding = "CP932") { options(warn = -1) if (is.na(dataName)) { stop("There is no data-name") } options(warn = 0) if (is.na(fileName)) { stop("There is no file-name") } if (!(is.character(fileName))) { stop("The file-name must be character") } data <- utils::read.table(paste0(dataName, ".csv"), fill = TRUE, header = FALSE, sep = ",", blank.lines.skip = FALSE, fileEncoding = fileEncoding) wb <- openxlsx::createWorkbook() openxlsx::addWorksheet(wb, "Sheet 1") st <- openxlsx::createStyle(fontName = fontName, fontSize = fontSize) openxlsx::addStyle(wb, "Sheet 1", style = st, cols = 1:2, rows = 1:2) openxlsx::writeData(wb, sheet = "Sheet 1", x = data, colNames = F, withFilter = F) openxlsx::modifyBaseFont(wb, fontSize = fontSize, fontColour = fontColor, fontName = fontName) init <- initialize(data, header = header, mode = "header") green_header <- init$gr_header footer <- init$footer col_intercept <- NA table_rightLim <- NULL if (adj == TRUE) { cols <- getPosition_intercpt_rightLim(green_header, data, col_intercept, table_rightLim) col_intercept <- cols$intercept table_rightLim <- cols$rightLim #setStyle for headers for (i in seq_len(length(green_header))) { st <- openxlsx::createStyle(fontName = fontName, fontSize = fontSize, fgFill = headerColor) openxlsx::addStyle(wb, "Sheet 1", style = st, cols = col_intercept[i]:table_rightLim[i], rows = green_header[i]) } factor_list <- list(NULL) factor_list <- mkFactorList(green_header, footer, factor_list, 1, data) #write data writeDatas(factor_list, data, wb) } else { st <- openxlsx::createStyle(fontName = fontName, fontSize = fontSize, fgFill = headerColor) for (k in seq_len(ncol(data))) { openxlsx::addStyle(wb, "Sheet 1", style = st, cols = k, rows = green_header) } factor_list <- list(NULL) factor_list <- mkFactorList(green_header, footer, factor_list, 1, data) #write data writeDatas(factor_list, data, wb) } openxlsx::saveWorkbook(wb, paste0(fileName, ".xlsx"), overwrite = TRUE) } |
関数excelHeadColorの引数については以下の表にまとめました。
dataName | 統計解析の結果が含まれているファイル名(csvのファイルのみ) | fontSize | フォントのサイズ |
fileName | 色塗り後の解析結果のファイル名 | fontName | フォント名 |
excelHeadColor | 色塗りするヘッダーに含まれる文字列(列名) | fontColor | フォントの色 |
excelHeadColorColor | 解析結果のヘッダーの色 | adj | TRUEの場合、検定結果の横のずれを修正する機能をもつ |
fileEncoding | ファイルエンコーディング。初期値は"CP932"。 |
関数の使用例
最後に使用例をプログラミングコードで紹介します。
excelColor
step
1解析結果を用意する
最初に検定結果を色塗りする関数excelColorの使用例を重回帰分析を例に、見ていきます。
まず、下の重回帰分析の結果の表をcsvに出力する関数を読み込んでください。(.Rをダウンロードもできます。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | reg_fun <- function(data, fileName, dependentVariable = NULL, level = 0.05 ,ci = TRUE ,sigma = FALSE, df = FALSE, R2 = TRUE, R =TRUE , R2.adj =TRUE, R.adj = FALSE, N=TRUE, dcml.plc = 5, AIC = TRUE, BIC = FALSE, append = TRUE){ if(is.null(dependentVariable)){dependentVariable <- colnames(data)[1]} y <- data[,dependentVariable] ans <- lm(y ~., data = data[, setdiff(colnames(data), dependentVariable)]) s.ans <- summary(ans) round(s.ans$coefficient,5) coe <- round(s.ans$coefficient,dcml.plc) ci <- round(cbind(s.ans$coefficients[,1]-qt(level/2, s.ans$df[2])*s.ans$coefficients[,2],s.ans$coefficients[,2]+qt(level/2, s.ans$df[2])*s.ans$coefficients[,2]),dcml.plc) colnames(ci) <- c(paste0(100-100*level, "%CI.low"), paste0(100-100*level, "%CI.up")) res <- cbind(coe, ci) if(df == TRUE){df <- data.frame(matrix(rep(round(s.ans$df, dcml.plc),nrow(coe)),nrow = 1 ))} if(R2 == TRUE){R2 <- round(s.ans$r.squared, dcml.plc)} if(R == TRUE){R <- round(sqrt(s.ans$r.squared), dcml.plc)} if(R2.adj == TRUE){R2.adj <- round(s.ans$adj.r.squared, dcml.plc)} if(R.adj == TRUE){R.adj <- round(sqrt(s.ans$adj.r.squared), dcml.plc)} if(AIC == TRUE){AIC <- round(AIC(ans), dcml.plc)} if(BIC == TRUE){BIC <- round(BIC(ans), dcml.plc)} if(N == TRUE){N <- nrow(data)} colName <- c("sigma","df","R", "R2", "R.adj", "R2.adj", "AIC", "BIC", "N") col_list <-list(sigma,df,R, R2, R.adj, R2.adj, AIC, BIC, N) for(i in 1:length(col_list)){ options(warn=-1) if(any(col_list[[i]]) != FALSE){ res <- cbind(res, col_list[[i]]) |