使用psych包做因子分析报错:需提供矩阵型x或x与y
解决R语言psych包因子分析中的数据类型与报错问题
看起来你在处理问卷数据做因子分析时踩了几个常见的坑,我来帮你一步步拆解问题并给出解决方案:
问题根源分析
从你的代码和报错信息能看出几个核心问题:
- 原始变量是因子类型:从
str(price_per_d)的输出可知,你的变量都是单水平或分类因子(比如price_per_d只有"Price (daily rate too high)"这一个水平),直接用gsub和as.numeric处理整个数据框是错误的——gsub会把整个数据框转换成一维字符向量,再转数值时非数字字符串自然会生成大量NA,最后fa.parallel因为收到一维向量而非多维数据框/矩阵,就会抛出supply both 'x' and 'y' or a matrix-like 'x'的错误。 - 变量变异不足:部分变量(比如
price_per_d)只有一个有效水平,这类变量方差为0,完全不适合参与因子分析,会干扰分析结果。
修正后的完整步骤
1. 先明确数据编码逻辑
根据你的变量名(比如price_per_d是“日租价格过高”),推测这些是多选问卷项:选中该选项记为非NA,未选中记为NA。我们需要把这类变量转换成二分数值(1=选中,0=未选中);如果是李克特量表类的有序因子,则需要提取对应数值。
2. 修正代码实现
library(psych) library(dplyr) # 简化数据处理 # 先查看所有目标变量的结构,确认每个因子的水平 str(zdf_base[, c("price_per_h", "price_per_d", "mileage", "one_way_option", "difficulties", "vehicle_types", "parking_spot","picking_up","availability", "dirty", "returning","refilling", "loalty_programs")]) # 提取需要的变量 Least_appealing <- subset(zdf_base, select=c("price_per_h", "price_per_d", "mileage", "one_way_option", "difficulties", "vehicle_types", "parking_spot","picking_up","availability", "dirty", "returning","refilling", "loalty_programs")) # 步骤1:剔除无变异的变量(比如只有1个水平的因子) # 先检查每个变量的水平数 sapply(Least_appealing, function(x) length(levels(x))) # 把水平数<=1的变量移除 Least_appealing_clean <- Least_appealing[, sapply(Least_appealing, function(x) length(levels(x)) > 1)] # 步骤2:将因子转换为数值(以二分变量为例:选中=1,未选中=0) Least_appealing_numeric <- Least_appealing_clean %>% mutate_all(~ ifelse(is.na(.), 0, 1)) # 如果你是李克特量表(比如因子水平是"1-非常不满意"这类带数字的),则用下面的代码提取数字: # library(stringr) # Least_appealing_numeric <- Least_appealing_clean %>% # mutate_all(~ as.numeric(str_extract(as.character(.), "\\d+"))) # 检查转换后的数据结构和摘要,确保没有异常 str(Least_appealing_numeric) summary(Least_appealing_numeric) # 现在运行fa.parallel fa.parallel(Least_appealing_numeric)
关键注意事项
- 一定要先检查变量的变异情况:无变异(水平数<=1)的变量必须剔除,否则因子分析无法正常运行。
- 因子转数值的逻辑必须匹配你的问卷设计:如果是多选则转二分,若是有序量表则提取对应分数,不能盲目转换。
- 转换后要检查数据摘要:确保NA都被正确处理,数值范围符合预期。
内容的提问来源于stack exchange,提问作者Papea
相关产品推荐
相关产品推荐

