R语言PAM聚类与t-SNE可视化报错:mutate不适用于factor类对象
解决
mutate应用于factor对象的报错 一、问题根源
报错Error in UseMethod("mutate") : no applicable method for 'mutate' applied to an object of class "factor"说明执行mutate前的对象是factor类型,而dplyr::mutate仅支持数据框/tibble对象。
二、分步排查与修复
1. 检查并修正数据列类型
先确认数据集df2的数值列不是factor类型:
str(df2)
如果health_expen、gdp_pc等列显示为Factor,转换为数值型:
library(dplyr) df2 <- df2 %>% mutate(across(c(health_expen, gdp_pc, life_exp, healthsoc_empl), as.numeric))
2. 明确调用dplyr的mutate函数
避免与其他包(如plyr)的同名函数冲突,所有mutate前加上dplyr::前缀:
# 聚类分析部分修正 pam_results <- df2 %>% dplyr::select(-country) %>% dplyr::mutate(cluster = pam_fit$clustering) %>% dplyr::group_by(cluster) %>% dplyr::do(the_summary = summary(.)) # t-SNE可视化部分修正 tsne_data <- tsne_obj$Y %>% data.frame() %>% setNames(c("X", "Y")) %>% dplyr::mutate(cluster = factor(pam_fit$clustering), name = df2$country)
3. 修正t-SNE的维度与参数设置
你设置了dims=3(3维),但后续只命名了2列(X、Y),建议统一维度为2(适配2D可视化),同时调整perplexity值(样本数为6时,perplexity建议设为2-5):
tsne_obj <- Rtsne(gower_dist, is_distance = TRUE, dims = 2, perplexity = 2)
4. 验证Gower距离矩阵的正确性
确保gower_dist是标准的距离矩阵(class为dist),用cluster::daisy计算:
library(cluster) gower_dist <- daisy(df2[, -1], metric = "gower") class(gower_dist) # 输出应为"dist"
三、完整可运行代码示例
library(cluster) library(dplyr) library(Rtsne) library(ggplot2) # 构造数据集 df2 <- tibble( country = c("Australia", "Austria", "Belgium", "Canada", "Chile", "Colombia"), health_expen = c(5130., 5624., 5353., 5190., 2297., 1293.), gdp_pc = c(52669., 58076., 54278., 49299., 25189., 15662.), life_exp = c(82.9, 82, 82.1, 82.3, 80.6, 76.6), healthsoc_empl = c(68, 53.0, 56.4, 59.9, 26.5, 18.4) ) # 计算Gower距离 gower_dist <- daisy(df2[, -1], metric = "gower") # PAM聚类 pam_fit <- pam(gower_dist, diss = TRUE, k = 2) # 聚类结果分析 pam_results <- df2 %>% dplyr::select(-country) %>% dplyr::mutate(cluster = pam_fit$clustering) %>% dplyr::group_by(cluster) %>% dplyr::do(the_summary = summary(.)) pam_results$the_summary # 查看medoids df2[pam_fit$medoids, ] # t-SNE可视化 tsne_obj <- Rtsne(gower_dist, is_distance = TRUE, dims = 2, perplexity = 2) tsne_data <- tsne_obj$Y %>% data.frame() %>% setNames(c("X", "Y")) %>% dplyr::mutate(cluster = factor(pam_fit$clustering), name = df2$country) ggplot(tsne_data, aes(x = X, y = Y)) + geom_point(aes(color = cluster), size = 3) + geom_text(aes(label = name), vjust = -1)
内容的提问来源于stack exchange,提问作者katehasnoidea
相关产品推荐
相关产品推荐

