使用for循环对不同链接方法执行层次聚类的代码问题咨询
错误原因
问题来源于R语言列表赋值的索引符号使用错误,与agnes对象结构、列表嵌套能力无关。R中列表的两种索引符号[和[[功能存在明确差异:
[返回的是子列表,赋值时会默认将右侧对象拆解为列表结构,仅取匹配长度的元素存入。agnes返回的S3对象本质为列表结构,使用ClustH[i] <- agnes(...)赋值时,仅会把agnes对象的第一个元素(即order字段)存入子列表。[[直接访问列表内的单个元素本身,支持存入任意类型的对象,包括嵌套列表、S3/S4对象等。
R列表完全支持嵌套存储任意类型的对象,不存在存储限制。
解决方案
方案1:修改for循环的赋值符号
把for循环里的ClustH[i]改为ClustH[[i]]即可,修正后的代码如下:
library(cluster) Links <- c("single","average","ward") ClustH <- list() set.seed(123) A <- rnorm(3, mean = 5, sd = 1) B <- rnorm(3, mean = 2, sd = 1) C <- rnorm(3, mean = 0, sd = 1) DMat <- as.dist(cbind(A,B,C)) for(i in 1:length(Links)){ # 用[[ ]]赋值存入完整agnes对象 ClustH[[i]] <- agnes(DMat, method = Links[i]) } # 验证:可以正常访问agnes对象的所有字段 ClustH[[1]]$method # 正确返回对应链接方法
方案2:用lapply生成列表(更符合R语法的简洁写法)
不需要手动写for循环和索引,直接用lapply批量生成结果并存入列表,还可以直接给列表元素命名方便后续调用:
library(cluster) Links <- c("single","average","ward") set.seed(123) A <- rnorm(3, mean = 5, sd = 1) B <- rnorm(3, mean = 2, sd = 1) C <- rnorm(3, mean = 0, sd = 1) DMat <- as.dist(cbind(A,B,C)) # 直接生成存储所有agnes对象的列表,同时绑定方法名 ClustH <- setNames(lapply(Links, function(m) agnes(DMat, method = m)), Links) # 可直接按方法名调用对应聚类结果 ClustH$ward
内容的提问来源于stack exchange,提问作者MicroBiostat
相关产品推荐
相关产品推荐

