You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

含有序变量的CFA问题:观测变量频率异常排查求助

有序变量CFA分析空类别报错问题解决

问题场景

  • 环境:RStudio(R 4.2.0),使用lavaan包做验证性因子分析(CFA)
  • 模型配置:10个因子、103个有序观测变量,样本量n=284
  • 模型代码:
library(lavaan)

modelshort <- '
comm=~Comm3+Comm5+Comm6+Comm8+Comm10+Comm19+Comm20+Comm21+Comm23
rc=~RC2+RC6+RC7+RC9+RC10+RC11+RC12+RC13+RC14+RC15+RC16+RC17+RC19+RC20+RC21+RC24
as=~AS6+AS8+AS9+AS14+AS15+AS16+AS17+AS18+AS19+AS20+AS21+AS22+AS23+AS24+AS26
vd=~VD1+VD2+VD3+VD4+VD5+VD9+VD10+VD12+VD16+VD21+VD23
ss=~SS5+SS7+SS8+SS9+SS10+SS13+SS15+SS16+SS17+SS19+SS20
loisirs=~Loisirs6+Loisirs7+Loisirs8+Loisirs12+Loisirs13+Loisirs14+Loisirs15+Loisirs16+Loisirs17+Loisirs18
auto=~Auto15+Auto16+Auto17+Auto18+Auto20+Auto22+Auto23+Auto24
ri=~RI2+RI3+RI4+RI7+RI14+RI17+RI18+RI21+RI22+RI23+RI24+RI25
asoc=~ASoc6+ASoc7+ASoc8+ASoc9+ASoc11+ASoc15+ASoc16+ASoc17+ASoc18+ASoc19+ASoc20
travail=~Travail1+Travail3+Travail4+Travail5+Travail6+Travail8+Travail9+Travail10+Travail11+Travail20+Travail22+Travail23'

出现的问题

  • 不指定有序变量时,模型运行正常:
fitshortord <- cfa(modelshort, data=abas6)
  • 添加ordered=TRUE参数后触发报错:
fitshortord <- cfa(modelshort, data=abas6, ordered=TRUE)

Error in lav_samplestats_step1(Y = Data, wt = wt, ov.names = ov.names, :
lavaan ERROR: some categories of variable `ASoc6' are empty in group 1; frequencies are [21 70 113 0]

  • 用plyr包查看频数时结果异常:
library(plyr)

count(ASoc6)
# Error in count(ASoc6) : object 'ASoc6' not found

count('ASoc6')
#       x freq
# 1 ASoc6    1
  • 原始SPSS文件中ASoc6的频数为[1,30,101,152],变量已确认导入RStudio;移除ASoc6后,ASoc11出现相同报错。

问题原因与解决步骤

1. 频数查看错误的纠正

plyr::count()需要传入数据框+变量名的组合,单独传变量名或字符串无法获取真实数据的频数。正确操作:

# 方式1:用plyr查看
count(abas6, ASoc6)
# 方式2:用base R更直接可靠
table(abas6$ASoc6, useNA = "ifany")

之前的错误操作导致你无法看到R中变量的真实分布,这是定位问题的关键。

2. lavaan报错的核心原因

lavaan提示空类别,说明R的abas6数据中,该变量确实存在无观测值的类别,和SPSS数据不符,大概率是数据导入时的编码/类型问题:

  • SPSS中的有序分类变量带标签,导入R后标签与数值编码不匹配,导致类别被错误转换;
  • 导入时缺失值处理不当,某类别的观测值被误判为缺失;
  • 变量在R中是数值型而非因子型,lavaan识别有序变量时按数值区间划分,出现空区间。

3. 具体解决步骤

步骤1:确认变量的真实状态

先查看变量的类型和准确频数:

# 查看变量类型
class(abas6$ASoc6)
# 查看包含缺失值的频数分布
table(abas6$ASoc6, useNA = "ifany")

步骤2:修复变量的类别编码

如果变量是数值型,转换为有序因子,确保和SPSS的类别一致:

# 假设SPSS中类别为1-4,按顺序定义
abas6$ASoc6 <- factor(abas6$ASoc6, levels = c(1,2,3,4), ordered = TRUE)
# 再次验证频数
table(abas6$ASoc6)

若存在缺失值,根据研究需求处理:

  • 缺失值少的话,可删除对应行:abas6 <- na.omit(abas6)
  • 缺失值多的话,考虑多重插补,不建议直接删除变量。

步骤3:精准指定有序变量

如果不是所有变量都是有序的,不要用ordered=TRUE,而是指定具体的有序变量列表,避免lavaan误判:

# 替换为你的103个有序变量名称
ordered_vars <- c("Comm3", "Comm5", "Comm6", ..., "ASoc6", ...)
fitshortord <- cfa(modelshort, data=abas6, ordered=ordered_vars)

步骤4:处理空类别(若确实存在)

如果确认某类别无观测值(比如导入时编码错误导致),可合并相邻类别:

# 示例:将第4类合并到第3类,根据实际情况调整
library(forcats)
abas6$ASoc6 <- fct_collapse(abas6$ASoc6, 
                            "3" = c("3", "4"))
# 验证合并后的频数
table(abas6$ASoc6)

内容的提问来源于stack exchange,提问作者claudio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 00:52:48