如何将R中多列表MSE计算代码转换为dplyr管道操作?
用dplyr管道符简化MSE计算的R代码验证与优化
原代码实现
你原本的MSE计算代码可以正常运行,代码如下:
seg_mean <- list(c(3.5,2.5),c(6.5,5.5),c(9.2,8.8),c(5.3,4.7)) mean_tot <- list(c(3,3),c(6,6),c(9,9),c(5,5)) seg_len <- list(20,18,17,15) MSE <- mapply('-', seg_mean, mean_tot, SIMPLIFY = FALSE) # 逐元素计算差值 MSE <- lapply(MSE, function(x) x^2) # 逐元素平方 MSE <- mapply('/', MSE, seg_len, SIMPLIFY = FALSE) # 每个元素除以对应seg_len
你设想的写法问题
你尝试的管道写法存在参数匹配错误:
MSE <- mapply('-', seg_mean, mean_tot, SIMPLIFY = FALSE) %>% lapply(function(x) x^2) %>% mapply('/', seg_len, SIMPLIFY = FALSE)
最后一步的mapply只传入了seg_len,管道符会把前一步的输出(平方后的差值列表)作为mapply的第一个参数,但mapply的第一个参数要求是函数,这会导致参数类型不匹配,代码无法运行。
可行的管道方案
修正mapply的管道写法
利用管道符的.指代前一步的输出,调整mapply的参数顺序即可:
library(dplyr) MSE <- mapply('-', seg_mean, mean_tot, SIMPLIFY = FALSE) %>% lapply(function(x) x^2) %>% mapply('/', ., seg_len, SIMPLIFY = FALSE)
这里的.代表前一步得到的平方后差值列表,作为/函数的第一个参数,seg_len作为第二个参数,实现逐元素除法。
更简洁的tidyverse风格写法
结合purrr包(与dplyr同属tidyverse生态)的map2函数,代码逻辑会更直观,避免mapply的参数混淆:
library(dplyr) library(purrr) MSE <- map2(seg_mean, mean_tot, `-`) %>% map(~ .x^2) %>% map2(seg_len, `/`)
map2(seg_mean, mean_tot,-):逐对计算两个列表的元素差值,替代mapply('-', ...)map(~ .x^2):对每个列表元素做平方,替代lapply(...)map2(seg_len,/):逐对将平方后的值除以对应seg_len,代码可读性更强
内容的提问来源于stack exchange,提问作者Arnoneel Sinha
相关产品推荐
相关产品推荐

