Chris
Chris

Reputation: 391

Use 2 grouping variables in a 3D lattice plot in R

I'm trying to produce a 3D cloud plot using the lattice package in R. I'd like colors and symbols to be grouped by two different factors on the plot. I found this example of how to do this using xyplot, but i'm having trouble adapting it for the cloud function (see code for Fig. 9.2):

http://lmdvr.r-forge.r-project.org/figures/figures.html?chapter=09;figure=09_02;theme=stdBW;code=right

In particular, there is a "subscripts" argument in panel.xyplot that is not present in panel.cloud, and i'm not sure how to change that part of my code.

Here's a self contained example of what i'm doing using the mtcars data set. The commented out code in the "panel = " part of the cloud call is what I want to fix. I'd like to color the data points by the variable cyl, and use different symbols to denote different clusters (from a kmeans analysis). Any suggestions are much appreciated.

# data
data(mtcars)

# kmeans
set.seed(321)
km <- kmeans(x = mtcars[, c(1, 3:7)], centers = 3, nstart = 1000)
mtcars$cluster <- factor(km$cluster)
mtcars$cyl <- factor(mtcars$cyl)

# pca
form <- formula(c("~", paste0(colnames(mtcars[, c(1, 3:7)]), collapse = "+")))
pca <- prcomp(form, data = mtcars[, c(1, 3:7)])

library(lattice)
library(RColorBrewer)

# set colors and points
colr <- brewer.pal(3, "Set1") 
pchr <- 0:2 

# set plot options
par.set <- list(axis.line = list(col = "transparent"),
                clip = list(panel = "off"),
                superpose.symbol = list(pch = pchr,
                                        col = colr))

# cloud plot
cloud(x[, "PC3"] ~ x[, "PC1"] * x[, "PC2"], 
     data = pca,
     zlab = "PC3", xlab = "PC1", ylab = "PC2",
     cex = 1, 
     groups = mtcars$cluster,
     type = "p",
     main = "3 cluster solution",
     screen = list(z = 20, x = -70, y = 3),
     par.settings = par.set,
     scales = list(col = "black"),
     #panel = function(x, y, z, subscripts, ...) {
     #          pch <- pchr[mtcars$cluster[subscripts]]
     #          col <- colr[mtcars$cyl[subscripts]]
     #          panel.cloud(x, y, z, pch = pch, col = col) },
     key = list(points = list(type = "p", pch = pchr, col = "black", cex = 1.2),
                text = list(paste("Cluster", levels(mtcars$cluster))),
                points = list(type = "p", pch = 1, col = colr, cex = 1.2),
                text = list(paste("Cyl", levels(mtcars$cyl))),
                columns = 1))

Upvotes: 0

Views: 800

Answers (1)

IRTFM
IRTFM

Reputation: 263301

You can omit the groups argument and substitute a pch and a col argument:

  ... , pch=mtcars$cyl, col=mtcars$cluster, ...

(Just to clarify why I wrote there was not an "x"-object: In R a named element of a list is not considered an object. In your case you were able to access that element because of your use of the data argument which allowed access to that element of the object "pca" within a local environment. I incorrectly surmised that you would not be able to use expressions of the form x[,"PC3"] inside a formula. As it turned out you were able to get them evaluated correctly.)

Upvotes: 1

Related Questions