You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

计算类间成对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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 03:50:39