R语言学习记录之踩坑cat()、print()与ifelse()

最近在复习学习R语言的基础语法,收获不少。
在学习到自定义函数当中使用 “…” 作为 可选参数,或者 不定长参数 时,发现一般使用“…”作为可选参数的,一般有两个作用:

  • 获取额外参数,将这些额外参数传递给其他函数,典型的是apply函数族当中的函数,如:

     > apply(X, MARGIN, FUN, ...)
      ... optional arguments to FUN
    
  • 获取不定数量参数的输入,即不确定会有多少个参数输入,或者函数允许接受可变数量的参数,比较典型的是paste()、paste0()等函数,如:

     >paste (..., sep = " ", collapse = NULL)
      paste0(..., collapse = NULL)
      ... one or more R objects, to be converted to character vectors.
    

那么,一个很自然的问题,如何获取 “…”
答案是:使用list(…)捕获输入的可变参数,并对其进行处理。
下面是一个自己用来练手的很简单的例子,然而就在这个例子里,让我重温了一下ifelse()、cat()以及print()几个函数的特点,例子如下:

#创建一个函数
f<-function(arg1,arg2 = "second_default",...){
	other<-list(...)
	cat("the arg1 is",arg1,'\n')
	cat("the arg2 is",ifelse(arg2 == "second_default","the defualt!",arg2),"\n")
	ifelse(length(other)!=0,cat('the othrs are NULL'),cat("the others is",other))
	}

从代码上看似乎没啥问题,那么执行代码:

> f(arg1 = "the first one",arg2 = "the second one",'OK',"I'm the optional parameter")
[1] the arg1 is the first one 
[2] the arg2 is the second one 
the othrs are NULLError in ans[ypos] <- rep(yes, length.out = len)[ypos] : 更换参数长度为零
此外: Warning message:
In rep(yes, length.out = len) : 'x' is NULL so the result will be NULL

发生了什么?为啥不对?从提示消息来看,是rep()重复函数存在问题,这样看是cat()函数有问题,那么把cat()换成print()试一下?
测试代码如下:

#单独测试cat()函数,结果依然:
>ifelse(2!=0,cat('the othrs are NULL'),cat("the others is",2))
[1] the othrs are NULLError in ans[ypos] <- rep(yes, length.out = len)[ypos] : 更换参数长度为零
此外: Warning message:
In rep(yes, length.out = len) : 'x' is NULL so the result will be NULL
#测试print()函数,有两次输入
>ifelse(2!=0,print('the othrs are NULL'),print("the others is",2))
[1] "the othrs are NULL"
[2] "the othrs are NULL"

这样的结果,有点让人费解。所幸查ifelse()函数的帮助文档,发现:

ifelse(test, yes, no)是针对if-else语句的向量化版本,因为如果输入结果(判断条件)是向量,在if-else语句当中只会取逻辑向量的第一个元素作为判断条件,无法实现向量化操作;而ifelse()函数可以针对test判断向量的每个元素的真/假,一一对应的返回yes与no中相应元素,即test[1]为真,则函数返回yes[1],反之返回no[1],其余类推;
yes、no和test之间的匹配,遵循向量化匹配原则;

这样,结果就清楚了,最大的可能性在cat()函数和print()函数的返回值上,做个测试:

#对cat()函数的返回值测试
> x<-cat("this is test code","for cat function!")
> x
[1] this is test code for cat function!
[2] NULL
#测试print()的返回值
> y<-print("this is test code for print function")
> y
[1] "this is test code for print function"
[2] "this is test code for print function"
#使用if(test)yes else no改写之前的函数
> if(2!=0) cat('the othrs are NULL') else cat("the others is",2)
[1] the othrs are NULL

果然如此,ifelse()函数要求yes和no起码是一个单值向量,而cat()函数作为向控制台输出打印的函数,其没有返回值,返回值为NULL;而print()函数则是在控制台输出打印的同时也会把输出内容返回到变量中。这也就是为什么使用cat()函数会导致ifesle()函数报错,而使用print()函数则会有两次输出的原因。
修改一下,同时需要注意的是,如果是可变参数用来存储不确定个数的实参输入,最好的方式是将“…”放在形参列表的最前边;另外,最佳的参数传递和函数调用方式,是同时按照形参名(arg=obj)和形参位置顺序来传递实参,这样将避免参数传递的混乱,避免意外错误。

f<-function(...,arg1,arg2='second_default'){
  other<-list(...)
  cat("the arg1 is",arg1,'\n')
  cat("the arg2 is",ifelse(arg2 == "one","the defualt!",arg2),"\n")
  cat("the optional parameter is:","\n")
  if(length(other)==0) cat("NULL") else return(other)
}
f(arg1 = "the first one",arg2 = "the second one",'OK',"I'm the optional parameter")

运行结果:

the arg1 is the first one 
the arg2 is the second one 
the optional parameter is: 
[[1]]
[1] "OK"

[[2]]
[1] "I'm the optional parameter"

另外,还有一个点,cat()函数是不支持对列表进行拼接输出的

  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值