计算类间成对Bhattacharyya相似度时遇strsplit错误求排查
成对Bhattacharyya相似度计算错误排查与修复
问题背景
我基于模拟数据计算不同类别间的成对Bhattacharyya相似度,用来衡量不同物种在多变量上的相似程度。数据服从正态分布且同方差,单独用bio3d::bhattacharyya.matrix计算两类相似度能正常运行,但运行自定义的pairwise.bhattacharyya函数时出现错误:
Error in strsplit (pattern, NULL): "pattern" argument absent, with no default value
推测错误来自bhattacharyya.matrix函数,求排查线索。
原始代码:
library(dyplr) library(bio3d) dummy.dataset<- data.frame(groups=c(rep("A",3),rep("B",3),rep("C",3),rep("D",3),rep("E",3)), X1=rnorm(15,0,1),X2=rnorm(15,0,1),X3=rnorm(15,0,1), X5=rnorm(15,0,1)) A.subset <–subset(dummy.dataset, groups=="A") B.subset <–subset(dummy.dataset, groups=="B") bio3d::bhattacharyya.matrix(cov(A.subset[,-1]), cov(B.subset[,-1]))#works pairwise.bhattacharyya <- function (d, g){ if (!is.factor(g)) { g = factor(g) } n = length(levels(g)) N = n * n Z = matrix(rep(NA_real_, N), ncol = n) rownames(Z) = levels(g) colnames(Z) = levels(g) for (i in 1:(n - 1)) { for (j in (i + 1):n) { Datax = subset(d, g == levels(g)[i]) Datax.num <- dplyr::select(where(is.numeric)) Datay = subset(d, g == levels(g)[j]) Datay.num <- dplyr::select(where(is.numeric)) Z[,j]<- bhattacharyya.matrix(cov(Datax.num),cov(Datay.num)) } Z[i,]<- bhattacharyya.matrix(cov(Datax.num),cov(Datay.num)) } return(Z) } pairwise.bhattacharyya(d=dummy.dataset, g=dummy.dataset$groups)
错误排查与修复说明
核心错误原因
自定义函数中的dplyr::select(where(is.numeric))未指定目标数据框!这导致Datax.num和Datay.num不是预期的分组数值子集,而是返回了函数环境的无效对象。后续计算协方差时得到非法结果,传给bhattacharyya.matrix后触发内部strsplit报错(函数接收到非矩阵/非数值的无效输入)。
其他问题修正
- 包名拼写错误:
library(dyplr)应为library(dplyr) - 循环逻辑错误:外层循环的赋值语句位置错误,且引用了内层循环的临时变量
- 赋值方向错误:
Z[,j]是整列赋值,但bhattacharyya.matrix返回单个数值,应填充对称矩阵的对应位置Z[i,j]和Z[j,i] - 新增对角线填充:同一类别的相似度应为1,符合逻辑
修正后的代码
library(dplyr) library(bio3d) dummy.dataset<- data.frame(groups=c(rep("A",3),rep("B",3),rep("C",3),rep("D",3),rep("E",3)), X1=rnorm(15,0,1),X2=rnorm(15,0,1),X3=rnorm(15,0,1), X5=rnorm(15,0,1)) A.subset <- subset(dummy.dataset, groups=="A") B.subset <- subset(dummy.dataset, groups=="B") # 验证单个计算正常运行 bio3d::bhattacharyya.matrix(cov(A.subset[,-1]), cov(B.subset[,-1])) pairwise.bhattacharyya <- function(d, g){ if (!is.factor(g)) { g <- factor(g) } levels_g <- levels(g) n <- length(levels_g) Z <- matrix(NA_real_, nrow = n, ncol = n, dimnames = list(levels_g, levels_g)) # 对角线为同一类别,相似度设为1 diag(Z) <- 1 for (i in 1:(n - 1)) { for (j in (i + 1):n) { # 提取对应组的数值列,明确指定数据框 Datax <- d[g == levels_g[i], ] %>% select(where(is.numeric)) Datay <- d[g == levels_g[j], ] %>% select(where(is.numeric)) # 计算Bhattacharyya相似度 bhatt_val <- bhattacharyya.matrix(cov(Datax), cov(Datay)) # 填充对称矩阵的两个位置 Z[i, j] <- bhatt_val Z[j, i] <- bhatt_val } } return(Z) } # 运行修正后的函数 pairwise.bhattacharyya(d=dummy.dataset, g=dummy.dataset$groups)
内容的提问来源于stack exchange,提问作者Manuel Tiburtini
相关产品推荐
相关产品推荐

