下标超出R的错误

时间:2015-02-04 12:14:52

标签: r factor-analysis

使用 stats 包中的factanal功能执行因子分析。

我尝试了以下事情。

library(mirt)
library(ltm)
library(psych)
library(stats)
data(SAT12)
data=SAT12
cor_mat=polychoric(data,  ML=TRUE, global=F)
 fit <- factanal(factors=2, n.obs=nrow(data), covmat=cor_mat$rho)


Divide_item_Factor_Loading(fit)

当我尝试运行Divide_item_Factor_Loading(fit)时出现一个名为

的错误
   Error in a[[i]][[2]] : subscript out of bounds 

弹出。

我的完整代码Divide_item_Factor_Loading:

Divide_item_Factor_Loading=function(fit)
{
  a=list()
  items=NULL
  for(i in 1:nrow(fit$loadings)) ######corresponding to rows of loading matrix
  {
    k=which(fit$loadings[i,]==max(abs(fit$loadings[i,])))  
    a[[i]]=c(i,as.numeric(k))
  } 
  fact_item_mat=matrix(, nrow=nrow(fit$loadings), ncol=ncol(fit$loadings))
  for(j in 1:(ncol(fit$loadings)))
  {
    for(i in 1:(nrow(fit$loadings)))
    {
      if(a[[i]][[2]]==j) {fact_item_mat[i,j]=a[[i]][[1]]}
    }    
  }
  nam=names(fit$loadings[,1])
  factor=list()
  for(i in 1:ncol(fit$loadings))
  {
    factor[[i]]=sort(fact_item_mat[,i], decreasing = FALSE, na.last = NA)
    fac=factor[[i]]
    fac=nam[fac]
    factor[[i]]=fac
  }
  names(factor)=paste("factor", 1:ncol(fit$loadings), sep="")
  return(factor)
}

我现在应采取哪些措施来避免此错误?

3 个答案:

答案 0 :(得分:1)

要更改加载的打印方式,请使用cutoff的{​​{1}}参数。

尝试这样的事情:

print.loadings

实际矩阵包含所有值。

print(fit$loadings, cutoff=0)

现在使用print(loadings(fit), cutoff=0) Loadings: Factor1 Factor2 Item 1 0.014 0.418 Item 2 0.130 0.350 Item 3 0.036 0.553 Item 4 0.166 0.294 Item 5 0.990 0.125 Factor1 Factor2 SS loadings 1.025 0.705 Proportion Var 0.205 0.141 Cumulative Var 0.205 0.346

提取每个因子的最大负载
apply()

答案 1 :(得分:0)

检查?loadings,你会发现有一个cutoff参数,它定义了一个值“小于此值(绝对值)的加载被抑制”。

答案 2 :(得分:0)

运行代码并调试你的功能(使用debug功能)我可以看到为什么你有一个&#34;下标超出界限&#34;错误:

  • 您的变量a的第15个元素(以及其他)的长度为1,因此R在您尝试到达a[[15]][2]时感到不满意......
  • 此元素仅为长度1而不是2的原因是因为达到负值的因子的最大绝对值,并且您要求哪个值(非绝对值)等于此最大绝对值,所以答案是没有......

因此您需要更改线路
 which(fit$loadings[i,]==max(abs(fit$loadings[i,])))which(abs(fit$loadings[i,])==max(abs(fit$loadings[i,])))
而且你会得到:

Divide_item_Factor_Loading(fit)
#$factor1
 #[1] "Item.1"  "Item.4"  "Item.6"  "Item.7"  "Item.8"  "Item.9"  "Item.10" "Item.11" "Item.13" "Item.14" "Item.15"
#[12] "Item.17" "Item.19" "Item.20" "Item.24" "Item.26" "Item.27" "Item.28" "Item.29"

#$factor2
 #[1] "Item.2"  "Item.3"  "Item.5"  "Item.12" "Item.16" "Item.18" "Item.21" "Item.22" "Item.23" "Item.25" "Item.30"
#[12] "Item.31" "Item.32"

即使已调试的功能现在可以使用,我认为您应该更改它,因为这比它应该更复杂。

我对替代功能的提议:

Divide_item_Factor_Loading_v2<-function(fit){
     a<-apply(fit$loadings,1,function(facs) which(abs(facs)==max(abs(facs))))
     return(list(factor1=names(a)[a==1],factor2=names(a)[a==2]))
}

这为您的fit对象提供与(调试的)函数完全相同的结果:

Divide_item_Factor_Loading_v2(fit)
#$factor1
 #[1] "Item.1"  "Item.4"  "Item.6"  "Item.7"  "Item.8"  "Item.9"  "Item.10" "Item.11" "Item.13" "Item.14" "Item.15"
#[12] "Item.17" "Item.19" "Item.20" "Item.24" "Item.26" "Item.27" "Item.28" "Item.29"

#$factor2
 #[1] "Item.2"  "Item.3"  "Item.5"  "Item.12" "Item.16" "Item.18" "Item.21" "Item.22" "Item.23" "Item.25" "Item.30"
#[12] "Item.31" "Item.32"