From 3b689cb09df12f030c568fadd4ff2010d19e5564 Mon Sep 17 00:00:00 2001 From: Vince Vu Date: Fri, 1 Aug 2014 09:33:12 -0400 Subject: [PATCH 1/9] Update ggbiplot.r --- R/ggbiplot.r | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/ggbiplot.r b/R/ggbiplot.r index 2111924..0dc83db 100644 --- a/R/ggbiplot.r +++ b/R/ggbiplot.r @@ -189,7 +189,7 @@ ggbiplot <- function(pcobj, choices = 1:2, scale = 1, pc.biplot = TRUE, ell <- ddply(df.u, 'groups', function(x) { if(nrow(x) < 2) { return(NULL) - } else if(nrow(x) == 2) { + } else if(nrow(x) > 2) { sigma <- var(cbind(x$xvar, x$yvar)) } else { sigma <- diag(c(var(x$xvar), var(x$yvar))) From efd5bfc8a975dca758da1c8a40ba569e282decdc Mon Sep 17 00:00:00 2001 From: Vince Vu Date: Fri, 1 Aug 2014 09:37:00 -0400 Subject: [PATCH 2/9] Fixed correlation ellipse. Fixed a bug in the ellipse drawing. The ellipse represents a contour of a bivariate Normal distribution with the same covariance matrix as the sample covariance matrix of the plotted principal components. When the number of observations is <= 2, the ellipse will not display because the sample covariance matrix will be degenerate. There was a bug in the conditional to check the number of observations that caused the off-diagonals to be ignored. This has been fixed. --- R/ggbiplot.r | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/R/ggbiplot.r b/R/ggbiplot.r index 0dc83db..164bae4 100644 --- a/R/ggbiplot.r +++ b/R/ggbiplot.r @@ -187,12 +187,10 @@ ggbiplot <- function(pcobj, choices = 1:2, scale = 1, pc.biplot = TRUE, circle <- cbind(cos(theta), sin(theta)) ell <- ddply(df.u, 'groups', function(x) { - if(nrow(x) < 2) { + if(nrow(x) <= 2) { return(NULL) - } else if(nrow(x) > 2) { + } else(nrow(x) > 2) { sigma <- var(cbind(x$xvar, x$yvar)) - } else { - sigma <- diag(c(var(x$xvar), var(x$yvar))) } mu <- c(mean(x$xvar), mean(x$yvar)) ed <- sqrt(qchisq(ellipse.prob, df = 2)) From 629f2c96889c7da429af4b31ca8c79eceaa34a46 Mon Sep 17 00:00:00 2001 From: Vince Vu Date: Fri, 1 Aug 2014 13:20:39 -0400 Subject: [PATCH 3/9] Fixed typo in else condition --- R/ggbiplot.r | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/R/ggbiplot.r b/R/ggbiplot.r index 164bae4..d319418 100644 --- a/R/ggbiplot.r +++ b/R/ggbiplot.r @@ -189,9 +189,8 @@ ggbiplot <- function(pcobj, choices = 1:2, scale = 1, pc.biplot = TRUE, ell <- ddply(df.u, 'groups', function(x) { if(nrow(x) <= 2) { return(NULL) - } else(nrow(x) > 2) { - sigma <- var(cbind(x$xvar, x$yvar)) } + sigma <- var(cbind(x$xvar, x$yvar)) mu <- c(mean(x$xvar), mean(x$yvar)) ed <- sqrt(qchisq(ellipse.prob, df = 2)) data.frame(sweep(circle %*% chol(sigma) * ed, 2, mu, FUN = '+'), From fd999409dfc8b52ec8d3ddb6341a14eafa7c7812 Mon Sep 17 00:00:00 2001 From: Ben Marwick Date: Mon, 12 Jan 2015 14:48:46 -0800 Subject: [PATCH 4/9] TRUEransparant -> transparent Just guessing that this is what you meant ;) --- R/ggbiplot.r | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/ggbiplot.r b/R/ggbiplot.r index d319418..e0e06e6 100644 --- a/R/ggbiplot.r +++ b/R/ggbiplot.r @@ -31,7 +31,7 @@ #' @param ellipse.prob size of the ellipse in Normal probability #' @param labels optional vector of labels for the observations #' @param labels.size size of the text used for the labels -#' @param alpha alpha transparency value for the points (0 = TRUEransparent, 1 = opaque) +#' @param alpha alpha transparency value for the points (0 = transparent, 1 = opaque) #' @param circle draw a correlation circle? (only applies when prcomp was called with scale = TRUE and when var.scale = 1) #' @param var.axes draw arrows for the variables? #' @param varname.size size of the text for variable names From 29582a998f24c1fb8a94b7e23da20ba16ffcd44d Mon Sep 17 00:00:00 2001 From: Maximilian Held Date: Sat, 30 May 2015 21:08:38 +0200 Subject: [PATCH 5/9] update install instructions original version yields a warning from devtools(): ``` Warning message: Username parameter is deprecated. Please use vqv/ggbiplot ``` --- README.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.markdown b/README.markdown index 0e94128..c6c37f0 100644 --- a/README.markdown +++ b/README.markdown @@ -11,7 +11,7 @@ Installation ------------ library(devtools) - install_github("ggbiplot", "vqv") + install_github("vqv/ggbiplot") Example Usage ------------- @@ -24,4 +24,4 @@ Example Usage g <- g + scale_color_discrete(name = '') g <- g + opts(legend.direction = 'horizontal', legend.position = 'top') - print(g) \ No newline at end of file + print(g) From 6c128f10059d901b9a7c3f6bdf0b2cb93d394d1c Mon Sep 17 00:00:00 2001 From: Jim Hester Date: Fri, 19 Jun 2015 08:50:37 -0400 Subject: [PATCH 6/9] Use an Rmd README to automatically generate an example plot --- .Rbuildignore | 2 ++ README-wine-example-1.png | Bin 0 -> 54761 bytes README.Rmd | 45 ++++++++++++++++++++++++++++++++++++++ README.markdown | 27 ----------------------- README.md | 30 +++++++++++++++++++++++++ 5 files changed, 77 insertions(+), 27 deletions(-) create mode 100644 README-wine-example-1.png create mode 100644 README.Rmd delete mode 100644 README.markdown create mode 100644 README.md diff --git a/.Rbuildignore b/.Rbuildignore index 91114bf..8453a6f 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -1,2 +1,4 @@ ^.*\.Rproj$ ^\.Rproj\.user$ +^README\.Rmd$ +^README-.*\.png$ diff --git a/README-wine-example-1.png b/README-wine-example-1.png new file mode 100644 index 0000000000000000000000000000000000000000..3e0873e66c26ae9e38d8ebbb4e5088710756e2d0 GIT binary patch literal 54761 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 M261v + +```{r, echo = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>", + fig.path = "README-" +) +``` + +ggbiplot +======== + +An implementation of the biplot using ggplot2. The package provides two functions: `ggscreeplot()` and `ggbiplot()`. +`ggbiplot` aims to be a drop-in replacement for the built-in R function `biplot.princomp()` with extended functionality +for labeling groups, drawing a correlation circle, and adding Normal probability ellipsoids. + +*The development of this software was supported in part by NSF Postdoctoral Fellowship DMS-0903120* + +Installation +------------ + +```r +library(devtools) +install_github("vqv/ggbiplot") +``` + +Example Usage +------------- + +```{r wine-example, message = FALSE, warning = FALSE} +library(ggbiplot) +data(wine) +wine.pca <- prcomp(wine, scale. = TRUE) +ggbiplot(wine.pca, obs.scale = 1, var.scale = 1, + groups = wine.class, ellipse = TRUE, circle = TRUE) + + scale_color_discrete(name = '') + + theme(legend.direction = 'horizontal', legend.position = 'top') +``` diff --git a/README.markdown b/README.markdown deleted file mode 100644 index c6c37f0..0000000 --- a/README.markdown +++ /dev/null @@ -1,27 +0,0 @@ -ggbiplot -======== - -An implementation of the biplot using ggplot2. The package provides two functions: `ggscreeplot()` and `ggbiplot()`. -`ggbiplot` aims to be a drop-in replacement for the built-in R function `biplot.princomp()` with extended functionality -for labeling groups, drawing a correlation circle, and adding Normal probability ellipsoids. - -*The development of this software was supported in part by NSF Postdoctoral Fellowship DMS-0903120* - -Installation ------------- - - library(devtools) - install_github("vqv/ggbiplot") - -Example Usage -------------- - - library(ggbiplot) - data(wine) - wine.pca <- prcomp(wine, scale. = TRUE) - g <- ggbiplot(wine.pca, obs.scale = 1, var.scale = 1, - groups = wine.class, ellipse = TRUE, circle = TRUE) - g <- g + scale_color_discrete(name = '') - g <- g + opts(legend.direction = 'horizontal', - legend.position = 'top') - print(g) diff --git a/README.md b/README.md new file mode 100644 index 0000000..d0eefcd --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ + +ggbiplot +======== + +An implementation of the biplot using ggplot2. The package provides two functions: `ggscreeplot()` and `ggbiplot()`. `ggbiplot` aims to be a drop-in replacement for the built-in R function `biplot.princomp()` with extended functionality for labeling groups, drawing a correlation circle, and adding Normal probability ellipsoids. + +*The development of this software was supported in part by NSF Postdoctoral Fellowship DMS-0903120* + +Installation +------------ + +``` r +library(devtools) +install_github("vqv/ggbiplot") +``` + +Example Usage +------------- + +``` r +library(ggbiplot) +data(wine) +wine.pca <- prcomp(wine, scale. = TRUE) +ggbiplot(wine.pca, obs.scale = 1, var.scale = 1, + groups = wine.class, ellipse = TRUE, circle = TRUE) + + scale_color_discrete(name = '') + + theme(legend.direction = 'horizontal', legend.position = 'top') +``` + +![](README-wine-example-1.png) From 7325e880485bea4c07465a0304c470608fffb5d9 Mon Sep 17 00:00:00 2001 From: Vince Vu Date: Fri, 19 Jun 2015 14:58:26 -0400 Subject: [PATCH 7/9] Added link to experimental branch --- README.Rmd | 2 ++ README.md | 3 +++ 2 files changed, 5 insertions(+) diff --git a/README.Rmd b/README.Rmd index 956460e..9e9424c 100644 --- a/README.Rmd +++ b/README.Rmd @@ -6,6 +6,8 @@ output: +**NEWS**: Active development of ggbiplot has moved to the [experimental branch](https://github.com/vqv/ggbiplot/tree/experimental) + ```{r, echo = FALSE} knitr::opts_chunk$set( collapse = TRUE, diff --git a/README.md b/README.md index d0eefcd..f4e3aeb 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ + +**NEWS**: Active development of ggbiplot has moved to the [experimental branch](https://github.com/vqv/ggbiplot/tree/experimental) + ggbiplot ======== From 87cc31cf3cc888c5df960501713f808f7d8f2497 Mon Sep 17 00:00:00 2001 From: EhrmannS Date: Mon, 23 Nov 2015 15:34:06 +0200 Subject: [PATCH 8/9] inclue additional graphics options (colour and alpha) for a set of defined columns. --- R/ggbiplot.r | 225 ++++++++++++++++++++++++++++-------------------- ggbiplot2.Rproj | 17 ++++ 2 files changed, 149 insertions(+), 93 deletions(-) create mode 100644 ggbiplot2.Rproj diff --git a/R/ggbiplot.r b/R/ggbiplot.r index e0e06e6..4145616 100644 --- a/R/ggbiplot.r +++ b/R/ggbiplot.r @@ -45,176 +45,215 @@ #' wine.pca <- prcomp(wine, scale. = TRUE) #' print(ggbiplot(wine.pca, obs.scale = 1, var.scale = 1, groups = wine.class, ellipse = TRUE, circle = TRUE)) #' -ggbiplot <- function(pcobj, choices = 1:2, scale = 1, pc.biplot = TRUE, - obs.scale = 1 - scale, var.scale = scale, - groups = NULL, ellipse = FALSE, ellipse.prob = 0.68, - labels = NULL, labels.size = 3, alpha = 1, - var.axes = TRUE, - circle = FALSE, circle.prob = 0.69, - varname.size = 3, varname.adjust = 1.5, - varname.abbrev = FALSE, ...) +ggbiplot2 <- function (pcobj, choices = 1:2, coi = "all", scale = 1, pc.biplot = TRUE, # incl. new arg + obs.scale = 1 - scale, var.scale = scale, groups = NULL, + ellipse = FALSE, ellipse.prob = 0.68, ellipse.alpha = 1, labels = NULL, labels.size = 3, + alpha = 1, var.axes = TRUE, circle = FALSE, circle.prob = 0.69, + varname.size = 3, varname.adjust = 1.5, varname.abbrev = FALSE, + arrow.color = muted("red"), arrow.linetype = "solid", arrow.alpha = 1, # incl. new args + ...) { library(ggplot2) library(plyr) library(scales) library(grid) - - stopifnot(length(choices) == 2) - + # Recover the SVD - if(inherits(pcobj, 'prcomp')){ + stopifnot(length(choices) == 2) + switch1 <- FALSE + if (inherits(pcobj, "prcomp")) { nobs.factor <- sqrt(nrow(pcobj$x) - 1) d <- pcobj$sdev - u <- sweep(pcobj$x, 2, 1 / (d * nobs.factor), FUN = '*') + u <- sweep(pcobj$x, 2, 1/(d * nobs.factor), FUN = "*") v <- pcobj$rotation - } else if(inherits(pcobj, 'princomp')) { + } else if (inherits(pcobj, "princomp")) { + # incl. switch to use later on for determination of package used for ordination. + switch1 <- TRUE nobs.factor <- sqrt(pcobj$n.obs) d <- pcobj$sdev - u <- sweep(pcobj$scores, 2, 1 / (d * nobs.factor), FUN = '*') + u <- sweep(pcobj$scores, 2, 1/(d * nobs.factor), FUN = "*") v <- pcobj$loadings - } else if(inherits(pcobj, 'PCA')) { + ln <- length(names(pcobj$scale)) + } else if (inherits(pcobj, "PCA")) { nobs.factor <- sqrt(nrow(pcobj$call$X)) d <- unlist(sqrt(pcobj$eig)[1]) - u <- sweep(pcobj$ind$coord, 2, 1 / (d * nobs.factor), FUN = '*') - v <- sweep(pcobj$var$coord,2,sqrt(pcobj$eig[1:ncol(pcobj$var$coord),1]),FUN="/") - } else if(inherits(pcobj, "lda")) { - nobs.factor <- sqrt(pcobj$N) - d <- pcobj$svd - u <- predict(pcobj)$x/nobs.factor - v <- pcobj$scaling - d.total <- sum(d^2) + u <- sweep(pcobj$ind$coord, 2, 1/(d * nobs.factor), FUN = "*") + v <- sweep(pcobj$var$coord, 2, sqrt(pcobj$eig[1:ncol(pcobj$var$coord), + 1]), FUN = "/") + } else if (inherits(pcobj, "lda")) { + nobs.factor <- sqrt(pcobj$N) + d <- pcobj$svd + u <- predict(pcobj)$x/nobs.factor + v <- pcobj$scaling + d.total <- sum(d^2) } else { - stop('Expected a object of class prcomp, princomp, PCA, or lda') + stop("Expected a object of class prcomp, princomp, PCA, or lda") } - + + # manage columns of interest (coi) + if(switch1){ + if(coi[1]=="all"){ + coi = list(c(names(pcobj$scale))) + cnoi = NULL + } else { + if(!is.list(coi)){ + stop("'coi' must be of type list") + } + cnoi <- names(pcobj$scale)[!names(pcobj$scale) %in% unlist(coi)] + } + lcoi <- length(coi) + lcnoi <- length(cnoi) + } + # Scores choices <- pmin(choices, ncol(u)) - df.u <- as.data.frame(sweep(u[,choices], 2, d[choices]^obs.scale, FUN='*')) - + df.u <- as.data.frame(sweep(u[, choices], 2, d[choices]^obs.scale, + FUN = "*")) + # Directions - v <- sweep(v, 2, d^var.scale, FUN='*') + v <- sweep(v, 2, d^var.scale, FUN = "*") df.v <- as.data.frame(v[, choices]) - - names(df.u) <- c('xvar', 'yvar') + + names(df.u) <- c("xvar", "yvar") names(df.v) <- names(df.u) - - if(pc.biplot) { + if (pc.biplot) { df.u <- df.u * nobs.factor } - + # Scale the radius of the correlation circle so that it corresponds to # a data ellipse for the standardized PC scores r <- sqrt(qchisq(circle.prob, df = 2)) * prod(colMeans(df.u^2))^(1/4) - + # Scale directions v.scale <- rowSums(v^2) - df.v <- r * df.v / sqrt(max(v.scale)) - + df.v <- r * df.v/sqrt(max(v.scale)) + # Change the labels for the axes - if(obs.scale == 0) { - u.axis.labs <- paste('standardized PC', choices, sep='') + if (obs.scale == 0) { + u.axis.labs <- paste("standardized PC", choices, sep = "") } else { - u.axis.labs <- paste('PC', choices, sep='') + u.axis.labs <- paste("PC", choices, sep = "") } - + # Append the proportion of explained variance to the axis labels - u.axis.labs <- paste(u.axis.labs, - sprintf('(%0.1f%% explained var.)', - 100 * pcobj$sdev[choices]^2/sum(pcobj$sdev^2))) - + u.axis.labs <- paste(u.axis.labs, sprintf("(%0.1f%% explained var.)", + 100 * pcobj$sdev[choices]^2/sum(pcobj$sdev^2))) + # Score Labels - if(!is.null(labels)) { + if (!is.null(labels)) { df.u$labels <- labels } - + # Grouping variable - if(!is.null(groups)) { + if (!is.null(groups)) { df.u$groups <- groups } - + # Variable Names - if(varname.abbrev) { + if (varname.abbrev) { df.v$varname <- abbreviate(rownames(v)) } else { df.v$varname <- rownames(v) } - + # Variables for text label placement - df.v$angle <- with(df.v, (180/pi) * atan(yvar / xvar)) - df.v$hjust = with(df.v, (1 - varname.adjust * sign(xvar)) / 2) - + df.v$angle <- with(df.v, (180/pi) * atan(yvar/xvar)) + df.v$hjust = with(df.v, (1 - varname.adjust * sign(xvar))/2) + + # colour management + if(switch1){ + alphas <- rep(1, ln) + colours <- rep(muted("red"), ln) + if(lcoi+1 != length(arrow.color) || lcoi+1!= length(arrow.linetype) || lcoi+1!= length(arrow.alpha)){ + warning("styles can maybe not be changed meaningfully when the respective arguments don't have same lenghts.") + } + for(i in 1:(lcoi+1)){ + if(i==1){ + alphas[ names(pcobj$scale) %in% cnoi] <- arrow.alpha[i] + colours[ names(pcobj$scale) %in% cnoi] <- arrow.color[i] + } else { + alphas[ names(pcobj$scale) %in% coi[[i-1]] ] <- arrow.alpha[i] + colours[ names(pcobj$scale) %in% coi[[i-1]] ] <- arrow.color[i] + } + } + } + # Base plot - g <- ggplot(data = df.u, aes(x = xvar, y = yvar)) + - xlab(u.axis.labs[1]) + ylab(u.axis.labs[2]) + coord_equal() - - if(var.axes) { + g <- ggplot(data = df.u, aes(x = xvar, y = yvar)) + xlab(u.axis.labs[1]) + + ylab(u.axis.labs[2]) + coord_equal() + + if (var.axes) { # Draw circle - if(circle) - { - theta <- c(seq(-pi, pi, length = 50), seq(pi, -pi, length = 50)) - circle <- data.frame(xvar = r * cos(theta), yvar = r * sin(theta)) - g <- g + geom_path(data = circle, color = muted('white'), + if (circle) { + theta <- c(seq(-pi, pi, length = 50), seq(pi, -pi, + length = 50)) + circle <- data.frame(xvar = r * cos(theta), yvar = r * + sin(theta)) + g <- g + geom_path(data = circle, color = muted("white"), size = 1/2, alpha = 1/3) } - + # Draw directions - g <- g + - geom_segment(data = df.v, - aes(x = 0, y = 0, xend = xvar, yend = yvar), - arrow = arrow(length = unit(1/2, 'picas')), - color = muted('red')) + g <- g + + geom_segment(data = df.v, + aes(x = 0, y = 0, xend = xvar, yend = yvar), + arrow = arrow(length = unit(1/2, "picas")), + color = colours, + linetype = arrow.linetype, + alpha = alphas) } - + # Draw either labels or points - if(!is.null(df.u$labels)) { - if(!is.null(df.u$groups)) { + if (!is.null(df.u$labels)) { + if (!is.null(df.u$groups)) { g <- g + geom_text(aes(label = labels, color = groups), size = labels.size) } else { - g <- g + geom_text(aes(label = labels), size = labels.size) + g <- g + geom_text(aes(label = labels), size = labels.size) } } else { - if(!is.null(df.u$groups)) { + if (!is.null(df.u$groups)) { g <- g + geom_point(aes(color = groups), alpha = alpha) } else { - g <- g + geom_point(alpha = alpha) + g <- g + geom_point(alpha = alpha) } } - + # Overlay a concentration ellipse if there are groups - if(!is.null(df.u$groups) && ellipse) { + if (!is.null(df.u$groups) && ellipse) { theta <- c(seq(-pi, pi, length = 50), seq(pi, -pi, length = 50)) circle <- cbind(cos(theta), sin(theta)) - - ell <- ddply(df.u, 'groups', function(x) { - if(nrow(x) <= 2) { + + ell <- ddply(df.u, "groups", function(x) { + if (nrow(x) <= 2) { return(NULL) } sigma <- var(cbind(x$xvar, x$yvar)) mu <- c(mean(x$xvar), mean(x$yvar)) ed <- sqrt(qchisq(ellipse.prob, df = 2)) - data.frame(sweep(circle %*% chol(sigma) * ed, 2, mu, FUN = '+'), - groups = x$groups[1]) + data.frame(sweep(circle %*% chol(sigma) * ed, 2, + mu, FUN = "+"), groups = x$groups[1]) }) - names(ell)[1:2] <- c('xvar', 'yvar') - g <- g + geom_path(data = ell, aes(color = groups, group = groups)) + names(ell)[1:2] <- c("xvar", "yvar") + g <- g + geom_path(data = ell, aes(color = groups, group = groups), alpha = ellipse.alpha) } - + # Label the variable axes - if(var.axes) { + if (var.axes) { g <- g + - geom_text(data = df.v, - aes(label = varname, x = xvar, y = yvar, - angle = angle, hjust = hjust), - color = 'darkred', size = varname.size) + geom_text(data = df.v, + aes(label = varname, x = xvar, y = yvar, angle = angle, hjust = hjust), + color = colours, + size = varname.size, + alpha = alphas) } # Change the name of the legend for groups # if(!is.null(groups)) { # g <- g + scale_color_brewer(name = deparse(substitute(groups)), # palette = 'Dark2') # } - + # TODO: Add a second set of axes - + return(g) -} +} \ No newline at end of file diff --git a/ggbiplot2.Rproj b/ggbiplot2.Rproj new file mode 100644 index 0000000..21a4da0 --- /dev/null +++ b/ggbiplot2.Rproj @@ -0,0 +1,17 @@ +Version: 1.0 + +RestoreWorkspace: Default +SaveWorkspace: Default +AlwaysSaveHistory: Default + +EnableCodeIndexing: Yes +UseSpacesForTab: Yes +NumSpacesForTab: 2 +Encoding: UTF-8 + +RnwWeave: Sweave +LaTeX: pdfLaTeX + +BuildType: Package +PackageUseDevtools: Yes +PackageInstallArgs: --no-multiarch --with-keep.source From b1a3e0b26aee162f6ca51b35622a5bc9f1ff8189 Mon Sep 17 00:00:00 2001 From: EhrmannS Date: Mon, 23 Nov 2015 16:48:17 +0200 Subject: [PATCH 9/9] update documentation, include linestypes as well... --- R/ggbiplot.r | 6 ++++-- man/ggbiplot.Rd | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/R/ggbiplot.r b/R/ggbiplot.r index 4145616..b8cb99f 100644 --- a/R/ggbiplot.r +++ b/R/ggbiplot.r @@ -92,7 +92,7 @@ ggbiplot2 <- function (pcobj, choices = 1:2, coi = "all", scale = 1, pc.biplot = # manage columns of interest (coi) if(switch1){ - if(coi[1]=="all"){ + if(coi=="all"){ coi = list(c(names(pcobj$scale))) cnoi = NULL } else { @@ -171,9 +171,11 @@ ggbiplot2 <- function (pcobj, choices = 1:2, coi = "all", scale = 1, pc.biplot = if(i==1){ alphas[ names(pcobj$scale) %in% cnoi] <- arrow.alpha[i] colours[ names(pcobj$scale) %in% cnoi] <- arrow.color[i] + linetypes[ names(pcobj$scale) %in% cnoi] <- arrow.linetype[i] } else { alphas[ names(pcobj$scale) %in% coi[[i-1]] ] <- arrow.alpha[i] colours[ names(pcobj$scale) %in% coi[[i-1]] ] <- arrow.color[i] + linetypes[ names(pcobj$scale) %in% coi[[i-1]] ] <- arrow.linetype[i] } } } @@ -199,7 +201,7 @@ ggbiplot2 <- function (pcobj, choices = 1:2, coi = "all", scale = 1, pc.biplot = aes(x = 0, y = 0, xend = xvar, yend = yvar), arrow = arrow(length = unit(1/2, "picas")), color = colours, - linetype = arrow.linetype, + linetype = linetypes, alpha = alphas) } diff --git a/man/ggbiplot.Rd b/man/ggbiplot.Rd index 82e2070..8f2bb4f 100644 --- a/man/ggbiplot.Rd +++ b/man/ggbiplot.Rd @@ -15,6 +15,14 @@ \item{choices}{which PCs to plot} + \item{coi}{define a set of columns of the original + data-frame (variables) which should be coloured in a + certain way. This has to be a list with as many list + elements as there should be different colours in the + final plot. Each list element should contain these + variable names, that should be coloured in the specified + colours.} + \item{scale}{covariance biplot (scale = 1), form biplot (scale = 0). When scale = 1, the inner product between the variables approximates the covariance and the @@ -59,6 +67,18 @@ \item{varname.abbrev}{whether or not to abbreviate the variable names} + + \item{arrow.color}{define a vector of colours which + should be applied to the names specified in 'coi'. The + length of this vector needs to be the lenght of coi + (which is a list) + 1. The first element should be the + colour for all unspecified elements (default colour).} + + \item{arrow.linetype}{same as arrow.colour, only for + linetype of the arrows.} + + \item{arrow.alpha}{same as arrow.colour, only for + linetype of the arrows.} } \value{ a ggplot2 plot