-1

I am just writing a R function to do PCA on certain covariance matrix. Here when I tried to use eigen function to get eigenvalues and eigenvectors the compiler says the object could not be found. Is there any way I can fix the problem? My code is listed below:

lab3<-function(cov,scale){ 
  if (scale==F)
  cov<-cov2cor(cov)

  dimension<-nrow(cov)
  eig<-eigen(cov)$values
  total<-sum(eig)
  stdev<-sqrt(eig)
  rotation<-eigen(cov)$vectors
  indp<-c(1:dimension)
  cump<-c(1:dimension)
  for (i in 1:dimension)
  {indp[i]=eig[i]/total
   cump[i]=sum(eigenvalue[1:i])/total
  }

  output=list(stdev,rotation,indp,cump)

}

Thanks.

The input can be just d<-matrix(c(1,-2,0,-2,5,0,0,0,2),3) then lab3(d,T) to run the code .. I am really sorry for the confusion caused. I didn't intend to do that and just I didn't know that. Thanks for your time.

Gavin Simpson
  • 170,508
  • 25
  • 396
  • 453
Junting Zhu
  • 111
  • 1
  • 8
  • 1
    Can you add some sample data? – Roman Luštrik Mar 27 '13 at 16:12
  • I don't understand what you mean? Here I am stuck at part to find eigenvalue and vectors of the cov matrix in the argument. No sample data is required. – Junting Zhu Mar 27 '13 at 16:15
  • Hi there! Please make your post reproducible. Read the post [**how to make a great reproducible example**](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) on how to do this. Thank you. – Arun Mar 27 '13 at 16:18
  • 2
    (1) The message wasn't from a compiler. R is an interpreted language. (2) "the object could not be found"? What object? Surely there was an actual error message? Was it really too difficulty to copy+paste it into your question? (3) Determining _why_ the object wasn't found will, in fact, require a complete reproducible example. – joran Mar 27 '13 at 16:20
  • @joran "R has no compiler" - really?? ;-) – Gavin Simpson Mar 27 '13 at 16:22
  • @GavinSimpson Stop picking my nits! :) – joran Mar 27 '13 at 16:23
  • 2
    Line `for (i=1:dimension)` looks weird, that is not a proper syntax for `for` loop, try this instead: `for(i in 1:dimension)`. – Jouni Helske Mar 27 '13 at 16:41
  • @Hemmo Good spot (+1) but the loop is not needed either. For example, see my Answer. Seems the error occurred much earlier in the `if(scale == F)` statement. – Gavin Simpson Mar 27 '13 at 17:02

1 Answers1

4

The immediate problem is that in

cump[i]=sum(eigenvalue[1:i])/total

you refer to eigenvalue which does not exist. I presume you meant to use eig here instead:

cump[i]=sum(eig[1:i])/total

From the comment the error seems to be:

as.vector(x, mode) : cannot coerce type 'closure' to vector of type 'any'

This results I suspect because you call the function without specifying scale. R will then find the scale function (a closure) and that can't be coerced to a type needed for the if() statement. An easy way to solve this is to do one of:

lab3 <- function(cov, scale = FALSE) {
....

or

lab3 <- function(cov) {
  if(missing(scale))
    scale <- FALSE
....

with the first form preferred.

There are other issues;

  1. surely you want

    if(scale)
      cov <- cov2cor(cov)
    

    ? I.e. only if you want all variables scaled to zero mean unit variance is correlation matrix required,

  2. the for loop can be done more efficiently with these two lines:

    indp <- eig / total
    cump <- cumsum(indp)
    

    You there don't need the for loop at all, and you don't need to set up indp and cump first either.

  3. you call eigen() twice. Better call it once and save the entire returned object. The subset that for the bits you want.

If I solve all these issues then we have the following function:

lab3 <- function(cov, scale=FALSE){ 
  if (scale)
    cov <- cov2cor(cov)

  ed <- eigen(cov)
  eig <- ed$values
  total <- sum(eig)
  stdev <- sqrt(eig)
  rotation <-ed$vectors
  indp <- eig / total
  cump <- cumsum(eig)

  list(stdev, rotation, indp, cump)
}

Which works:

> lab3(cov(iris[, 1:4]))
[[1]]
[1] 2.0562689 0.4926162 0.2796596 0.1543862

[[2]]
            [,1]        [,2]        [,3]       [,4]
[1,]  0.36138659 -0.65658877 -0.58202985  0.3154872
[2,] -0.08452251 -0.73016143  0.59791083 -0.3197231
[3,]  0.85667061  0.17337266  0.07623608 -0.4798390
[4,]  0.35828920  0.07548102  0.54583143  0.7536574

[[3]]
[1] 0.924618723 0.053066483 0.017102610 0.005212184

[[4]]
[1] 4.228242 4.470912 4.549122 4.572957

Finally, I'll note that doing PCA via a singular value decomposition is considered better than via an eigen decomposition for reasons of numerical stability. And you can do all of this via princomp or preferably prcomp, both in base R.

Gavin Simpson
  • 170,508
  • 25
  • 396
  • 453
  • Thanks for your reply. Similar problem still occurs: as.vector(x, mode) : cannot coerce type 'closure' to vector of type 'any' for the line eig<-eigen(cov)$values Sorry I am quite new to R. – Junting Zhu Mar 27 '13 at 16:32
  • @JuntingZhu Before you write another comment, you need to go back and edit your question as requested to include reproducible code. – joran Mar 27 '13 at 16:42
  • (+1) for going beyond what was stated. – Ferdinand.kraft Mar 27 '13 at 16:45
  • Yes, my downvote for your question, @JuntingZhu, is because it is not useful for you to post a question for which you are obstinately refusing to post a data example that would make the error messages interpretable. – IRTFM Mar 27 '13 at 16:46
  • @joran Thanks. Maybe my understanding is not correct but what I asked was only a function and no sample data is needed. I will remember that next time. Sorry I am just required to do some labs using R but I didn't have any courses for R so I tended to make silly mistakes. :) – Junting Zhu Mar 27 '13 at 16:48
  • I am really sorry for the confusion caused. I didn't intend to do that and just I didn't know that. Thanks for your time. – Junting Zhu Mar 27 '13 at 16:54
  • @JuntingZhu The reason people ask for sample data is so they can run your code to see what the problems are. If you make it easy for people here to see what the problem is, you'll get faster, more-informed responses. Believe it or not, even the best coders can't always look at a chunk of code and immediately spot the mistakes. As you are asking for help for free, please make it as easy as possible for them to help you. – Gavin Simpson Mar 27 '13 at 17:01