0

There are quite some answers to this question. Not only on stack overflow but through internet. However, none could solve my problem. I have two problems

I try to simulate a data for you

df <- structure(list(Group = c(1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 
2, 2, 2), var1 = c(2, 3, 1, 2, 3, 2, 3, 3, 5, 6, 7, 6, 8, 5, 
5), var2 = c(9, 9, 9, 8, 7, 8, 9, 3, 2, 2, 1, 1, 2, 3, 3), var3 = c(6, 
7, 6, 6, 5, 6, 7, 1, 2, 1, 2, 3, 1, 1, 2)), .Names = c("Group", 
"var1", "var2", "var3"), row.names = c(NA, -15L), class = "data.frame")

then I do as follows:

fit <- lda(Group~., data=df)
plot(fit)

I end up with groups appearing in two different plots.

how to plot my results in one figure like e.g. Linear discriminant analysis plot Linear discriminant analysis plot using ggplot2

or any other beautiful plot ?

Community
  • 1
  • 1
  • Because you only have two groups, only one LD is calculated. In your sample plot there were two LD's calculated so it made sense to map one to the x-axis and one to the y-axis. With two groups you only get LD1 so a univariate barplot is draw. What do you want on each of the axis for your desired plot? – MrFlick Feb 28 '15 at 16:09

1 Answers1

2

The plot() function actually calls plot.lda(), the source code of which you can check by running getAnywhere("plot.lda"). This plot() function does quiet a lot of processing of the LDA object that you pass in before plotting. As a result, if you want to customize how your plots look, you will probably have to write your own function that extracts information from the lda object and then passes it to a plot fuction. Here is an example (I don't know much about LDA, so I just trimmed the source code of the default plot.lda and use ggplot2 package (very flexible) to create a bunch of plots).

#If you don't have ggplot2 package, here is the code to install it and load it
install.packages("ggplot2")
library("ggplot2")
library("MASS")


#this is your code. The only thing I've changed here is the Group labels because you want a character vector instead of numeric labels
df <- structure(list(Group = c("a", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b"),
                         var1 = c(2, 3, 1, 2, 3, 2, 3, 3, 5, 6, 7, 6, 8, 5, 5), 
                         var2 = c(9, 9, 9, 8, 7, 8, 9, 3, 2, 2, 1, 1, 2, 3, 3), 
                         var3 = c(6, 7, 6, 6, 5, 6, 7, 1, 2, 1, 2, 3, 1, 1, 2)),
                    .Names = c("Group","var1", "var2", "var3"),
                    row.names = c(NA, -15L), class = "data.frame")
fit <- lda(Group~., data=df)

#here is the custom function I made that extracts the proper information from the LDA object. You might want to write your own version of this to make sure it works with all cases (all I did here was trim the original plot.lda() function, but I might've deleted some code that might be relevant for other examples)

ggplotLDAPrep <- function(x){
  if (!is.null(Terms <- x$terms)) {
    data <- model.frame(x)
    X <- model.matrix(delete.response(Terms), data)
    g <- model.response(data)
    xint <- match("(Intercept)", colnames(X), nomatch = 0L)
    if (xint > 0L) 
      X <- X[, -xint, drop = FALSE]
  }
  means <- colMeans(x$means)
  X <- scale(X, center = means, scale = FALSE) %*% x$scaling
  rtrn <- as.data.frame(cbind(X,labels=as.character(g)))
  rtrn <- data.frame(X,labels=as.character(g))
  return(rtrn)
}

fitGraph <- ggplotLDAPrep(fit)

#Here are some examples of using ggplot to display your results. If you like what you see, I suggest to learn more about ggplot2 and then you can easily customize your plots

#this is similar to the result you get when you ran plot(fit)
ggplot(fitGraph, aes(LD1))+geom_histogram()+facet_wrap(~labels, ncol=1)

#Same as previous, but all the groups are on the same graph
ggplot(fitGraph, aes(LD1,fill=labels))+geom_histogram()

The following example won't work with your example because you don't have LD2, but this is equivalent to the scatter plot in the external example you provided. I've loaded that example here as a demo

ldaobject <- lda(Species~., data=iris)
fitGraph <- ggplotLDAPrep(ldaobject)
ggplot(fitGraph, aes(LD1,LD2, color=labels))+geom_point()

I didn't customize ggplot settings much, but you can make your graphs look like anything you want if you play around with it.Hope this helps!

grittlydev
  • 143
  • 1
  • 8
  • there is something wrong with you plot. Please look at your data! you have 2 classes (a and b ) in the plot you show three classes ! Strange !!!! –  Feb 28 '15 at 23:54
  • I've realized I was missing a line of code. Should work now. Regarding 3 classes on the plot, that was because the last ggplot call was using a different example. I moved that into a separate code section now. Also please run the code line by line (or scroll through the plots that were generated because each ggplot line overrides the previous) – grittlydev Mar 01 '15 at 00:03
  • 1
    you should use something like this instead for example , ggplot(fitGraph, aes(LD1,fill=labels))+geom_histogram(colour = "darkgreen", fill = "white", binwidth = 0.5) . –  Mar 01 '15 at 09:51