亚米UM 发表于 2016-1-16 13:25 
当你需要返回函数计算后的结果的时候就用return返回,如果单纯地画图或者存成文件等就不用Return了。你这 ...
首先纠正一个对R常见的误解:R的函数里不是必须用return()来返回结果的。R默认会返回函数体最后一行表达式的求值结果(这也是通常的情况),这点是R作为(偏)函数式语言和其他常见语言比如C++所不同的地方。引用一下R官方文档里的话(大家可以在console里输入?return查看):
If the end of a function is reached without calling return, the value of the last evaluated expression is returned.
在R里几乎所有的表达式都会有返回值,包括赋值(a<-1), 打印(print())。大家可以试试运行以下几个函数:
- fun0 <- function(){
- f0<<-"fun0"
- }
- fun1 <- function(){
- f1<<-"fun1"
- print(f1)
- }
- fun2 <- function(){
- plot(rnorm(100))
- }
- fun0()
- F0 <- fun0()
- fun1()
- F1 <- fun1()
- fun2()
- F2 <- fun2()
复制代码fun0和fun1的返回值被记录在F0和F1中,而base R里的plot函数没有返回值,所以F2的值是NULL。但是lattice,ggplot2这两个绘图包的所有绘图却都是有返回值的(返回值就是一个所有构成图表元素的数据结构,通常是List):
- fun3 <- function(){
- ggplot2::qplot(mpg, wt, data = mtcars)
- }
- fun4 <- function(){
- x <- rnorm(500)
- lattice::densityplot(~x)
- }
- fun3()
- F3 <- fun3()
- fun4()
- F4 <- fun4()
复制代码return在R里的作用在于从控制流中间(if/else,for循环等)提前返回值并退出函数体。看下面的例子:
- # Demonstrate the use of "return()" ----------------------------------
- fun5 <- function(y) {
- x <- sample(seq_len(y))
- for(i in 1:5){
- if(x[1]<5) {
- print(paste("x[1] =", x[1]))
- # return(sprintf("After %d times you got lucky!", i))
- return(print(paste("After",i,"times you got lucky", collapse = "")))
- } else {
- x <- sample(x)
- }
- }
- "Sorry, you didn't pick the winner soon enough!"
- }
- fun5(10)
- fun5(1000)
复制代码这是我随便编的一个函数,对1:y的整数进行随机排序,如果某一次随机排序的结果使得第一个数小于5那么会打印一句话,如果五次排序完成都没能满足这个条件那么打印另外一句话(大家不要介意函数的写法哈,要实现相同功能肯定会有更好的办法,这里只是演示return的作用)。
那么fun5(10)就会对1:10的整数进行随机排序,有很大的概率你们会看到if体内return的那句话,然后函数就退出执行了,因此函数体最后的那句话这时是看不到的。而调用fun5(1000)时满足if条件的概率会很小,所以就有很大可能看到函数体最后一行的那句字符串。
P.S. fun5最后我没有用print函数而是直接写了一个字符串,就是想表明字符串也是可以作为表达式存在并且被返回的。