R中含字符变量数据集使用scale函数及后续聚类分析相关问题
报错原因
scale() 函数仅支持对全数值类型的矩阵或数据框做Z-score标准化,只要数据集中存在1列及以上的字符、因子等非数值类型字段,就会触发这个错误。
小提示:如果你是直接运行示例代码
scale(USArrests)出现该报错,说明你之前不小心修改了R内置的USArrests数据集,重启R会话后重新运行即可恢复正常。
解决步骤
1. 排查非数值列
先确认你的数据集中哪些列是非数值类型:
# 查看所有列的类型 str(你的数据集名称) # 直接输出非数值列的列名 non_num_cols <- names(which(sapply(你的数据集名称, function(x) !is.numeric(x)))) non_num_cols
2. 处理非数值列
根据非数值列的业务意义选择处理方式:
- 如果是用户ID、地区名称这类无聚类参考价值的标识类字段,直接删除即可,仅保留数值列:
# 提取所有数值列生成新数据集 df_num <- 你的数据集名称[, sapply(你的数据集名称, is.numeric)]
- 如果是性别、产品类型这类有聚类价值的分类字段,需要先编码为数值:
- 无序分类变量(比如省份、职业,各取值无高低等级之分):用独热编码处理,推荐用
fastDummies包快速实现:
# 首次使用先安装包 install.packages("fastDummies") library(fastDummies) # 自动对所有分类列做独热编码,删除原始分类列 df_encode <- dummy_cols(你的数据集名称, remove_selected_columns = TRUE)- 有序分类变量(比如收入等级:低/中/高,满意度:差/一般/好,有明确等级顺序):可以按等级映射为连续数值,保留等级信息:
# 示例:将收入等级列转为数值 你的数据集名称$income_level <- factor(你的数据集名称$income_level, levels = c("低", "中", "高"), labels = c(1,2,3)) 你的数据集名称$income_level <- as.numeric(as.character(你的数据集名称$income_level)) - 无序分类变量(比如省份、职业,各取值无高低等级之分):用独热编码处理,推荐用
3. 执行标准化和聚类
处理得到全数值数据集后,即可正常运行标准化和kmeans聚类:
# 标准化,注意替换为你处理后的全数值数据集名称 df_scaled <- scale(df_num) # 运行kmeans聚类 km.res <- kmeans(df_scaled, 4, nstart = 10)
注意事项
- 标准化前建议先检查缺失值,可通过
sum(is.na(你的数据集名称))查看缺失值数量,存在缺失值时可以用na.omit()删除缺失行,或者用列均值/中位数填充,否则scale()也会运行报错。 - 如果你用了独热编码,且分类变量的取值非常多,建议先做特征筛选再聚类,避免维度过高影响聚类效果。
内容的提问来源于stack exchange,提问作者MJ_vdH
相关产品推荐
相关产品推荐

