R中的下标越界错误
Subscript out of bound error in R
同时使用 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)
}
我现在应该采取什么步骤来避免这个错误?
要更改载荷的打印方式,请将 cutoff
参数用于 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()
:
apply(loadings(fit), 2, max)
Factor1 Factor2
0.9895743 0.5531770
查看?loadings
,你会发现有一个cutoff
参数定义了一个"loadings smaller than this (in absolute value) are suppressed".
的值
运行 你的代码和调试你的函数(使用 debug
函数)我明白你为什么有 "subscript out of bound" 错误:
- 变量
a
的第 15 个元素(以及其他元素)的长度为 1,因此当您尝试达到 a[[15]][2]
时 R
不高兴...
- 这个元素的长度只有1而不是2的原因是因为factor的最大绝对值达到负值而你问的是哪个值(不是绝对值)等于这个最大绝对值, 所以答案是 none...
因此您需要更改行
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"
同时使用 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)
}
我现在应该采取什么步骤来避免这个错误?
要更改载荷的打印方式,请将 cutoff
参数用于 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()
:
apply(loadings(fit), 2, max)
Factor1 Factor2
0.9895743 0.5531770
查看?loadings
,你会发现有一个cutoff
参数定义了一个"loadings smaller than this (in absolute value) are suppressed".
运行 你的代码和调试你的函数(使用 debug
函数)我明白你为什么有 "subscript out of bound" 错误:
- 变量
a
的第 15 个元素(以及其他元素)的长度为 1,因此当您尝试达到a[[15]][2]
时R
不高兴... - 这个元素的长度只有1而不是2的原因是因为factor的最大绝对值达到负值而你问的是哪个值(不是绝对值)等于这个最大绝对值, 所以答案是 none...
因此您需要更改行
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"