R语言入门与实践
上QQ阅读APP看书,第一时间看更新

1.6 参数

如果我们把刚才构建的函数主体中的第一行代码删除,并将第二行代码中的参数die改成bones,会出现什么情况呢?

        roll2 <- function() {
          dice <- sample(bones, size = 2, replace = TRUE)
          sum(dice)
        }

现在运行这个新函数会导致R输出一条错误信息。这个新函数在调用时会去寻找bones,而我们根本没有定义过bones这个对象,于是导致错误的发生。

        roll2()
        ## Error in sample(bones, size = 2, replace =TRUE) :
        ##   object 'bones' not found

如果你将bones作为这个函数的一个参数名,就可以将bones再作为参数传递给sample函数。为此,我们在用function定义新函数roll2时,在其后的括号中键入bones作为该函数的参数。

        roll2 <- function(bones) {
          dice <- sample(bones, size = 2, replace = TRUE)
          sum(dice)
        }

只要你在调用新函数时将bones提供给该函数,roll2就有效。这个函数的好处是,在每次调用roll2函数时可以掷不同类型的骰子。现在我们可以去玩《龙与地下城》了!

记住,我们掷的是成对的骰子。

        roll2(bones = 1:4)
        ## 3
        roll2(bones = 1:6)
        ## 10
        roll2(1:20)
        ## 31

应该注意的是,如果你在调用roll2函数时不提供bones的值,那么roll2函数仍然会触发错误信息。

        roll2()
        ## Error in sample(bones, size = 2, replace = TRUE) :
        ##   argument "bones" is missing, with no default

为了防止类似的错误发生,你可以指定一个初始默认值给bones。为此,只需在定义roll2函数时将bones与相应的默认值用等号连接即可。

        roll2 <- function(bones = 1:6) {
          dice <- sample(bones, size = 2, replace = TRUE)
          sum(dice)
        }

对于现在这样一个新的roll2函数来说,你可以按照需求指定一个新的值给bones,如果不指定,其值就是默认值1:6。

        roll2()
        ## 9

你可以在自定义函数中设置任意数量的参数,只要在function后的括号中列出它们的名称,并且用逗号隔开即可。函数运行时,R会将函数主体中的每个参数名称替换为用户为该参数提供的值。如果用户没有设置参数值,那么R会用该参数的默认值代替(前提是在定义函数时设置了该参数的默认值)。

总的来说,function函数可以帮助你构建自定义R函数。函数的主体是function后面大括号中的代码。函数的参数在紧随function后的小括号中定义,参数名是自定义的。最后,你通过将函数的输出保存到某个R对象,给这个函数起一个名称,如图1-6所示。

图1-6:R中的任何一个函数都必须包含这三个部分,你可以用function函数分别定义这三个部分

创建了自定义函数之后,R对待它的方式与R中其他函数没有任何区别。你能想象这是多么有用吗?你有没有试过在Excel中编写一个自定义选项并将其加入到微软的菜单栏中?或者是在PowerPoint中添加一个新的动画效果?当你使用程序语言时,可以实现类似的任务。学会R编程之后,你将能够随时创造出新的、定制化的并可重复使用的工具。第三部分将详细介绍如何编写R函数。