R语言中outer与mahalanobis函数配合使用报错问题求助
解决R中outer函数结合mahalanobis时的维度不匹配错误
问题根源
outer函数的运行逻辑是向量化批量处理:它会把输入的x和y分别作为列向量和行向量,生成所有元素组合的矩阵式参数传递给目标函数,而不是逐个传递单个数值。
你的原函数fn是针对单个x、y值设计的:c(x,y)会把单个数值拼成2维向量,能被mahalanobis正常处理。但当outer调用它时,x和y实际是长度为50的向量,c(x,y)会生成长度100的向量,和mahalanobis要求的“每行一个2维样本”的输入格式完全不匹配,因此触发non-conformable arguments维度错误。
而fn <- function(x, y) x^2+y^2能运行,是因为R的算术运算本身支持向量广播,自动适配了outer的向量化输入。
解决方案
有两种简单的修复方式:
方式1:用Vectorize包装原函数
把原函数转换成支持向量化输入的版本,让outer能正确调用:
iris[c(1,51, 101),] x <- seq(0, 4, length=50) y <- seq(0, 4, length=50) seto<-subset(iris[1:50,],select=-Species) virgi<-subset(iris[101:150,],select=-Species) seto.m<-apply(seto[1:45,],2,mean) virgi.m<-apply(virgi[1:45,],2,mean) seto.v<-var(seto[1:45,]) virgi.v<-var(virgi[1:45,]) fn <- function(x, y) mahalanobis(c(x, y), seto.m[1:2], seto.v[1:2, 1:2]) fn(3, 4) # 正常运行 # 包装函数实现向量化支持 vec_fn <- Vectorize(fn) z <- outer(x, y, vec_fn) # 现在可正常生成z矩阵
方式2:直接修改函数适配批量输入
手动构造所有(x,y)组合的样本矩阵,直接传递给mahalanobis,效率会更高:
iris[c(1,51, 101),] x <- seq(0, 4, length=50) y <- seq(0, 4, length=50) seto<-subset(iris[1:50,],select=-Species) virgi<-subset(iris[101:150,],select=-Species) seto.m<-apply(seto[1:45,],2,mean) virgi.m<-apply(virgi[1:45,],2,mean) seto.v<-var(seto[1:45,]) virgi.v<-var(virgi[1:45,]) # 直接处理批量输入的函数 fn <- function(x, y) { # 生成所有x-y组合的2维样本矩阵,每行一个样本 xy_samples <- cbind(rep(x, length(y)), rep(y, each = length(x))) mahalanobis(xy_samples, seto.m[1:2], seto.v[1:2, 1:2]) } z <- outer(x, y, fn) # 正常运行
内容的提问来源于stack exchange,提问作者hopstepforward
相关产品推荐
相关产品推荐

