R温度转换函数返回向量长度超出预期问题排查
问题原因
你的代码核心问题出在循环变量的取值逻辑上:你用了for (i in x),这会让i依次取向量x里的数值(也就是35、40、45),而非向量的位置索引(1、2、3)。
当你执行newX[i] <- ...时,R会自动把newX的长度扩展到i的最大值(这里是45),那些没被赋值的位置就会填充NA(初始的newX是长度3的0向量,后面扩展的位置为NA),这就是为什么你得到了超长的向量。
修正方案
有两种简洁的修正方式,推荐第二种(利用R的向量化特性):
方案1:修正循环的索引逻辑
把循环改成遍历位置索引,用for (i in seq_along(x))替代for (i in x),这样i会取1、2、3,对应向量的三个元素位置:
convTemp <- function(x, from = "C", to = "F") { newX <- vector("double", length(x)) if (from == to) { warning("Your 'from' parameter is the same as your 'to' parameter!") } if (from == "C" && to == "F") { for (i in seq_along(x)) { newX[i] <- ((9/5)*x[i]+32) } } if (from == "C" && to == "K") { for (i in seq_along(x)) { newX[i] <- (x[i]+273.15) } } if (from == "F" && to == "C") { for (i in seq_along(x)) { newX[i] <- ((x[i]-32)*(5/9)) } } if (from == "K" && to == "C") { for (i in seq_along(x)) { newX[i] <- (x[i]-273.15) } } if (from == "F" && to == "K") { for (i in seq_along(x)) { newX[i] <- ((((x[i]-32)*5)/9)+273.15) } } if (from == "K" && to == "F") { for (i in seq_along(x)) { newX[i] <- ((((x[i]-273.15)*9)/5)+32) } } return(newX) } # 测试 convTemp(c(35,40,45), from="F", to="K")
方案2:利用R的向量化操作(更高效简洁)
R天生支持向量级别的运算,完全不需要循环,代码会更简洁且运行更快:
convTemp <- function(x, from = "C", to = "F") { if (from == to) { warning("Your 'from' parameter is the same as your 'to' parameter!") return(x) } newX <- switch(paste(from, to, sep = "_"), "C_F" = (9/5)*x + 32, "C_K" = x + 273.15, "F_C" = (x - 32)*(5/9), "K_C" = x - 273.15, "F_K" = ((x - 32)*5/9) + 273.15, "K_F" = ((x - 273.15)*9/5) + 32, stop("Invalid 'from' or 'to' temperature scale!") ) return(newX) } # 测试 convTemp(c(35,40,45), from="F", to="K")
这个版本用switch替代了多个if判断,同时直接对整个向量做运算,避免了循环的问题,代码更易维护。
测试结果
修正后运行convTemp(c(35,40,45), from="F", to="K")会返回正确的3个开尔文数值:
[1] 274.8167 277.5944 280.3722
内容的提问来源于stack exchange,提问作者burble_gurp007
相关产品推荐
相关产品推荐

