在R中逐行应用fm.Choquet函数失败,求解决方案
问题解决:Rfmtool::fm.Choquet 应用到数据框行的维度错误修复
错误原因分析
你遇到的维度错误本质是三个核心不匹配:
- 环境初始化与N不匹配:你提到N=2,但如果用
fm.Init(2),则要求y的长度必须是2^2=4,但你只传入了2个元素(b和c); - rowwise中引用整列而非当前行:用
df$a或df[,2]会取整个列的数据,而非当前行的单个值; - 对参数规则的误解:
fm.Choquet的参数严格遵循:x是长度为N的输入向量y是长度为2^N的模糊测度向量env必须用fm.Init(N)初始化,三者维度完全对应
结合你的需求(每行用a作为x,b和c作为y),此时N=1(x长度为1),因此env需要用fm.Init(1)初始化,y长度为2^1=2,刚好匹配b和c的长度。
正确实现方法
方法1:使用dplyr rowwise
library(dplyr) library(Rfmtool) # 初始化正确的环境(N=1) env <- fm.Init(1) df2 <- df %>% rowwise() %>% # 直接引用当前行的列,而非整列 mutate(ci = fm.Choquet(x = a, y = c(b, c), env = env)) %>% ungroup() # 取消rowwise避免后续操作异常 # 查看结果 head(df2)
方法2:使用by()函数
env <- fm.Init(1) # 按行处理,注意引用当前行的row$a/row$b/row$c ci_results <- by(df, df$id, function(row) { fm.Choquet(x = row$a, y = c(row$b, row$c), env = env) }) # 将结果合并到原数据框 df$ci <- unlist(ci_results)
方法3:使用for循环(适合调试)
env <- fm.Init(1) df$ci <- NA_real_ for(i in seq_len(nrow(df))){ df$ci[i] <- fm.Choquet(x = df$a[i], y = c(df$b[i], df$c[i]), env = env) }
如果你实际需要N=2的场景
如果你的真实需求是用长度为2的x(比如每行的b和c),则需要准备长度为4的y向量(比如新增4列存储模糊测度),并初始化env <- fm.Init(2),示例代码框架如下:
env <- fm.Init(2) df <- df %>% rowwise() %>% # 假设y1-y4是存储模糊测度的4列 mutate(ci = fm.Choquet(x = c(b, c), y = c(y1, y2, y3, y4), env = env)) %>% ungroup()
内容的提问来源于stack exchange,提问作者timetraveller007
相关产品推荐
相关产品推荐

