改进 if else 语句

Improve if else statement

我在 R 中有以下功能。它工作正常,但是,我认为这一定是 运行 此功能的更好方法。

values <- c("a","b")


print <- function(values){
  
  size <- length(values)

  if (size == 1) {
  
  final <- values[1]
  
}else if(size == 2){
  
  final <- paste0(values[2], " and ", values[1])
}else if(size == 3){
  
  final <- paste0(values[3], " and ",values[2], " and ", values[1])
  
}
  return(final)
}
print(values)

用户可以改变值的大小,所以如果他选择values <- c("a","b", "c"),函数将在最后一个条件下运行。然而,最后一个条件在艺术上等于第二个条件加上一些新的东西。可以做一个 if 语句,或者在那些使用先前条件的行中做一些事情。类似于:

values <- c("a","b", "c")


print <- function(values){
  
  size <- length(values)

  if (size == 1) {
  
  final <- values[1]
  
}else if(size == 2){
  
  final <- paste0(values[2], " and ", final )
}else if(size == 3){
  
  final <- paste0(values[3], " and ",final )
  
}
  return(final)
}
print(values)

试试这个,它颠倒输入向量的顺序并在以下之间粘贴“和”:

newfun <- function(x){
  ifelse(length(x)>1, paste(rev(x), collapse = " and "), x)
}

输出:

newfun(letters[1])
 # [1] "a"

newfun(letters[1:2])]
 # [1] "b and a"

# and so on...

newfun(letters[1:5])
 # [1] "e and d and c and b and a"

根据您的函数测试它是否相同:

all.equal(print(letters[1:3]), 
          newfun(letters[1:3]))
# [1] TRUE

我也会 强烈 警告命名 user-defined R 中已经固有的函数名称(即 print() 已经是 R 中的函数。

另一种颠倒向量顺序的方法:

reverse_print <- function(values) paste(values[order(values, decreasing = TRUE)], collapse = " and ")

reverse_print(c("a", "b"))
#[1] "b and a"

reverse_print(c("a", "b", "c", "d"))
#[1] "d and c and b and a"

但是,如果您的主要 objective 是创建一个递归使用条件和先前条件的函数,实现它的一种方法是创建一个直接递归函数,其中函数调用自身 (请参阅@G.Chan的评论以供参考)。不幸的是,我未能为您的案例创建这样的功能。 Error: C stack usage 15927520 is too close to the limit 制作完成。这种错误在递归函数中比较常见,如讨论here.

我建议使用 while 和增量索引,而不是创建直接递归函数,如下所示:

revprint <- function(values) {
  size   <- length(values)
  if (size == 1) {
    cat(values[1])
  } else {
    while (size > 1) {
      final    <- values[size]
      appended <- paste0(final, " and ")
      size     <- size - 1
      output   <- cat(appended)
    }
    cat(output, values[1], sep = "")
  }
}

revprint("a")
# a

revprint(c("a", "b", "c", "d"))
# d and c and b and a

如果输入(字符向量)的长度大于 1,此函数使用 paste0 显示输入的最后一个字符,然后递增地减少输入的长度。在每个增量步骤中,显示新(较短)输入的最终字符,并附加上一个(较长)输入的最终字符。

因为这个函数使用了cat,结果显示在控制台上,但是不能直接赋值给一个对象。要将其分配给对象,您可以使用 capture.output()

out <- capture.output(revprint(c("a", "b", "c", "d")))
out
#[1] "d and c and b and a"