目的 R には,princomp および prcomp という,二種類の関数が用意されている。 しかし,これらが返す「loadings」は固有ベクトルそのものであって,いわゆる負荷量ではない。 ここに示す関数は,princomp を下請け関数として用いて,通常の主成分分析結果として提示するものである。 なお,pca という関数も書いたので,そちらも参照してみるとよい。 使用法 princomp2(dat, pcs=0, cor=TRUE, scores=FALSE, verbose=TRUE) 引数 dat データ行列(行がケース,列が変数) pcs 求める主成分の個数。 0 を指定する(デフォールト)と固有値が 1 以上の主成分を求める。 cor TRUE(デフォールト)の場合には相関係数行列を主成分分析する(変数の単位に異なるものがある場合にはこれを選択する以外の手はない)。 FALSE の場合には,分散・共分散行列を主成分分析する。 scores TRUEなら主成分得点を計算する。 vervose TRUE(デフォールト) なら,分析結果を print 文によって出力する FALSEの場合には,結果はリストによって返される。 戻り値 戻り値のリスト princomp が返すもの $sdev 固有値 $loadings 固有ベクトル(いわゆる負荷量ではない) $center 分析に使用した各変数の平均値 $scale 分析に使用した各変数の標準偏差(変動をデータの個数で割って平方根を取った方) $n.obs 分析に使用したケース数 $scores 主成分得点(分散が固有値になるように調整されたもの) 付加されたもの $loadings 整形された主成分分析結果(下記参照) $x 主成分得点(不偏分散が固有値になるように調整されたもの) ソース インストールは,以下の 1 行をコピーし,R コンソールにペーストする source("http://aoki2.si.gunma-u.ac.jp/R/src/princomp2.R", encoding="euc-jp") # princomp を援用して,主成分分析の結果をまとめる princomp2 <- function( dat, # データ行列 pcs=0, # 求める主成分の個数 cor=TRUE, # TRUE の場合には相関係数行列,FALSE なら分散共分散行列を対象にする scores=FALSE, # 主成分得点を計算するかどうか verbose=TRUE) # 饒舌に結果を表示するかどうか { p <- ncol(dat) # 変数の個数 if (is.null(colnames(dat))) colnames(dat) <- paste("Var", 1:p, sep=".") # 変数名がついていないとき n <- nrow(dat) # サンプルサイズ if (is.null(rownames(dat))) rownames(dat) <- paste("Obs", 1:n, sep=".") # 行名がついていないとき dat <- subset(dat, complete.cases(dat)) # 欠損値を持つケースを除く n <- nrow(dat) # サンプルサイズは小さくなったかもしれない result<-princomp(dat, cor=cor, scores=scores) # princomp を呼び出す if (pcs == 0) { # 抽出する主成分数が指定されていないときは, pcs <- sum(result$sdev^2 >= 1) # 1 以上の固有値の数 } loadings <- t(result$sde*t(result$loadings))[, 1:pcs, drop=FALSE] # 主成分負荷量 Contribution <- rowSums(loadings^2) # 寄与率 Eigen.values <- c(result$sdev[1:pcs]^2, sum(result$sdev[1:pcs]^2)) # 固有値 denominator <- if (cor) p else sum(diag(var(dat)*(n-1)/n)) # 累積寄与率を計算する分母(cor=FALSE なら,分散共分散行列の対角成分の和) Proportion <- Eigen.values/denominator*100 # 寄与率 Cumulative.prop. <- cumsum(Proportion) # 累積寄与率 Cumulative.prop.[pcs+1] <- NA # 末尾は不要 result$loadings <- rbind(cbind(loadings, Contribution), # 主要分析結果 Eigen.values, Proportion, Cumulative.prop.) result$x <- result$scores * sqrt((n-1)/n) # 主成分得点 if (verbose) { cat(sprintf("%16s", ""), sprintf("%8s", paste("PC", 1:pcs, sep="")), " Contribution\n", sep="") for (i in 1:p) { cat(sprintf("%-16s", rownames(result$loadings)[i]), sprintf("%8.3f", loadings[i,]), sprintf("%10.3f\n", Contribution[i]), sep="") } cat("Eigen.values ", sprintf("%8.3f", result$loadings[p+1, 1:pcs]), "\n", sep="") cat("Proportion ", sprintf("%8.3f", result$loadings[p+2, 1:pcs]), "\n", sep="") cat("Cumulative.prop.", sprintf("%8.3f", result$loadings[p+3, 1:pcs]), "\n", sep="") if (scores) { cat(sprintf("\n%16s", ""), sprintf("%8s", paste("PC", 1:pcs, sep="")), "\n", sep="") for (i in 1:n) { cat(sprintf("%-16s", rownames(result$scores)[i]), sprintf("%8.3f", result$scores[i, 1:pcs]), "\n", sep="") } } } invisible(result) } 使用例 dat <- matrix(c( # 10 ケース,5 変数のデータ行列例(ファイルから読んでも良い) -1.89, -0.02, 0.42, 1.23, -1.53, 0.06, 1.81, -0.59, -0.75, -0.12, 2.58, -0.20, -1.92, -0.49, -0.35, 0.69, -0.66, -0.77, -1.92, 0.38, -1.05, 0.07, -0.37, -0.89, -1.62, -2.73, 1.40, 0.18, -0.09, 0.13, 0.95, 0.84, 1.19, 1.19, 0.10, 0.93, 1.17, -1.70, 1.46, -0.25, -0.04, -0.12, -0.34, -0.24, 1.88, 0.16, 1.03, -0.05, -0.73, 0.04 ), byrow=TRUE, ncol=5) colnames(dat) <- paste("Var", 1:5, sep=".") # 変数名 rownames(dat) <- paste("case", 1:10, sep="-") # ケース名 princomp2(dat) 出力結果例 例 1 固有値が 1 以上の主成分を抽出し,結果を自動出力 > princomp2(dat) PC1 PC2 PC3 Contribution 因子負荷量,寄与率など Var.1 -0.767 0.448 -0.151 0.812 Var.2 0.530 0.618 0.144 0.684 Var.3 0.750 -0.249 0.387 0.774 Var.4 0.557 0.557 -0.324 0.726 Var.5 -0.357 0.302 0.848 0.937 Eigen.values 1.869 1.047 1.017 Proportion 37.375 20.932 20.342 Cumulative.prop. 37.375 58.306 78.648 例 2 2 つの主成分を抽出し,主成分得点とともに結果を自動出力 > princomp2(dat, pcs=2, scores=TRUE) PC1 PC2 Contribution Var.1 -0.767 0.448 0.789 Var.2 0.530 0.618 0.663 Var.3 0.750 -0.249 0.624 Var.4 0.557 0.557 0.621 Var.5 -0.357 0.302 0.218 Eigen.values 1.869 1.047 Proportion 37.375 20.932 Cumulative.prop. 37.375 58.306 PC1 PC2 主成分得点 case-1 1.868 -0.946 case-2 0.231 0.751 case-3 -2.405 0.379 case-4 -1.956 -1.385 case-5 0.293 -1.545 case-6 1.771 -0.196 case-7 1.205 0.863 case-8 -0.209 1.940 case-9 -0.898 0.052 case-10 0.100 0.087 例 3 例 1 と同じ出力をする別法 > ans <- princomp2(dat, pcs=0, scores=TRUE) > ans$loadings PC1 PC2 PC3 Contribution Var.1 0.7670549 0.4479912 -0.1511371 0.8119117 Var.2 -0.5301729 0.6180870 0.1441703 0.6838998 Var.3 -0.7496095 -0.2494103 0.3872449 0.7740785 Var.4 -0.5570003 0.5573622 -0.3239124 0.7258212 Var.5 0.3565268 0.3016596 0.8477030 0.9367101 Eigen.values 1.8687315 1.0465842 1.0171057 3.9324214 Proportion 37.3746303 20.9316843 20.3421134 78.6484280 Cumulative.prop. 37.3746303 58.3063146 78.6484280 NA > ans$scores PC1 PC2 PC3 PC4 PC5 case-1 1.8684045 -0.94576668 -1.2332697 -0.93926955 -0.3730075 case-2 0.2309233 0.75142992 0.3473489 1.47623977 0.4528447 case-3 -2.4045883 0.37897746 -1.1474093 -0.15470182 0.1186054 case-4 -1.9560246 -1.38510647 0.5622894 -0.06866507 0.1175167 case-5 0.2926468 -1.54510805 -1.0717479 0.52700054 0.1763542 case-6 1.7712949 -0.19635831 0.9154032 0.86695787 -0.6625894 case-7 1.2045357 0.86272982 0.4474658 -1.37756199 1.0911237 case-8 -0.2093047 1.94011453 -1.1422799 0.07247913 -0.7135016 case-9 -0.8983546 0.05163475 1.7564121 -0.93389874 -0.7875738 case-10 0.1004669 0.08745302 0.5657873 0.53141986 0.5802275 解説ページ