直接的问题是,在
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
....
首选第一种形式。
还有其他问题;
你肯定想要
if(scale)
cov <- cov2cor(cov)
? 即仅当您希望将所有变量缩放为零均值单位方差时才需要相关矩阵,
使用for
这两行可以更有效地完成循环:
indp <- eig / total
cump <- cumsum(indp)
你根本不需要循环,for
也不需要先设置。indp
cump
- 你打电话
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中完成所有这些操作。