-1

我只是在编写一个 R 函数来对某些协方差矩阵进行 PCA。在这里,当我尝试使用特征函数来获取特征值和特征向量时,编译器说找不到对象。有什么办法可以解决这个问题吗?我的代码如下:

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)

}

谢谢。

输入就可以d<-matrix(c(1,-2,0,-2,5,0,0,0,2),3) 运行lab3(d,T)代码了.. 造成的混乱真的很抱歉。我不打算这样做,只是我不知道。谢谢你的时间。

4

1 回答 1

4

直接的问题是,在

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

你指的是eigenvalue哪个不存在。我想你打算在eig这里使用:

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

从评论来看,错误似乎是:

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

我怀疑这是因为您在未指定的情况下调用该函数scale。然后,R 将找到scale函数(闭包),并且不能将其强制为if()语句所需的类型。解决此问题的一种简单方法是执行以下操作之一:

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

或者

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

首选第一种形式。

还有其他问题;

  1. 你肯定想要

    if(scale)
      cov <- cov2cor(cov)
    

    ? 即仅当您希望将所有变量缩放为零均值单位方差时才需要相关矩阵,

  2. 使用for这两行可以更有效地完成循环:

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

    你根本不需要循环,for也不需要先设置。indpcump

  3. 你打电话eigen()两次。最好调用一次并保存整个返回的对象。您想要的位的子集。

如果我解决了所有这些问题,那么我们有以下功能:

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)
}

哪个有效:

> 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

最后,我会注意到,出于数值稳定性的原因,通过奇异值分解进行 PCA 被认为比通过特征分解更好。您可以通过princomp或最好prcomp在基础 R中完成所有这些操作。

于 2013-03-27T16:21:13.463 回答