R语言十进制转三进制算法:sapply仅返回最后r的问题排查
解决R语言中sapply调用三进制转换函数仅返回最后一个结果的问题
嘿,我猜你遇到的问题大概率是函数内部没有使用局部变量存储转换结果,而是不小心用了全局环境里的r变量!这样每次调用ternary(n)时,都会在同一个r的基础上修改,最后所有元素的转换结果都会被最后一次的覆盖,自然只返回最后一个r的值了。
先看错误写法的典型例子(可能就是你的问题所在):
如果你之前的代码是这样的:
# 在函数外部定义了全局变量r r <- "" ternary <- function(n) { while(n > 0) { # 这里修改的是全局的r,不是函数内部的局部变量 r <- paste(n %% 3, r, sep = "") n <- n %/% 3 } return(r) } # 调用sapply时,所有调用共享同一个全局r sapply(c(5, 7, 10), ternary)
运行后你会发现结果全是最后一个数的三进制(比如"101"),因为每次调用ternary都在修改同一个全局r,前面的结果被后面的覆盖了。
正确的解决方法:在函数内部初始化局部变量
只需要把r的初始化放到函数内部,让每次调用ternary都创建独立的局部变量,互不干扰:
ternary <- function(n) { # 处理n=0的特殊情况,避免返回空字符串 if (n == 0) return("0") # 在函数内部初始化局部变量r,每次调用都是全新的 r <- "" while(n > 0) { r <- paste(n %% 3, r, sep = "") n <- n %/% 3 } return(r) } # 现在sapply就能正确返回每个数的三进制结果了 sapply(c(5, 7, 10, 0), ternary)
运行结果会是:"12" "21" "101" "0",完全符合预期。
额外补充:为什么会这样?
R语言中,函数会优先使用自己内部定义的变量(局部变量),如果没有找到,才会去全局环境找。你之前的写法让函数使用了全局的r,导致所有函数调用共享这个变量,结果被不断覆盖。把r放到函数内部后,每次调用函数都会生成一个只属于当前调用的r,自然就能保留每个数的转换结果了。
内容的提问来源于stack exchange,提问作者Student number x
相关产品推荐
相关产品推荐

