首页 > 解决方案 > 如何设置仅在输入 3 时才显示集合向量的函数?

问题描述

我正在尝试编写一个函数,该函数创建一个基于给定数字向上和向后计数的向量c(1:n, (n-1):1)。但是,当3输入时,我希望向量显示为1,1,1,2,2,2,3,3,3而不是1,2,3,2,1. 我试过使用if(n==3),但是当我尝试运行它时出现错误,上面写着“n cannot be found”,但我不太明白为什么。很感谢任何形式的帮助!这是我尝试过的:

vector<-function(n)
  c(1:n, (n-1):1)
  if(n==3)
    c(rep(1,3),rep(2,3),rep(3,3))

标签: r

解决方案


问题

问题中的代码有几个问题:

  • 函数中缺少 { ... },因此function实际上只有该行之后的第一行才会被视为函数的一部分。

  • 一个函数返回执行的最后一条语句的值,并且问题中执行的最后一条语句是 theif或 the 的主体,if因此该c(1:n, (n-1):1)语句被计算但永远不能返回。

  • 如果 n=1 然后c(1:n, (n-1):1)给出 1,0,1 这可能不是你想要的。

  • c(rep(1,3),rep(2,3),rep(3,3))就它给出的结果而言并没有错,但rep可以以更紧凑的方式使用。

  • 通常 x:y 不会在编程中使用,因为如果 y < x 那么它会意外地给出从 x 到 y 的值。在这种情况下,if语句排除了这种可能性,但您可能希望用适当的方式替换冒号seq下一节中的第二条腿的替代方案提供了这样的替代方案。

解决方案

而是试试这个。它首先检查 n 是否小于 1,如果是则返回零长度向量;否则,剩下if的用两条腿运行,一条腿用于 n = 1 或 n = 3 的情况,一条腿用于其余情况。

(如果您愿意只为 n > 0 做这项工作,那么我们可以省略第一个if。如果您只愿意做这项工作 n > 1,那么我们也可以在最后一个条件中省略 n==1if部分.)

myfun <- function(n) {
  if (n < 1) integer(0)
  else if (n == 1 || n == 3) rep(1:n, each = n)
  else c(1:n, (n-1):1)
}

给予:

myfun(-1)
## integer(0)

myfun(0)
## integer(0)

myfun(1)
## [1] 1

myfun(2)
## [1] 1 2 1

myfun(3)
## [1] 1 1 1 2 2 2 3 3 3

myfun(4)
## [1] 1 2 3 4 3 2 1

最后一站的替代方案 if

以下是第一回合的一些替代方案,即n <- 3.

rep(1:n, each = n)
## [1] 1 1 1 2 2 2 3 3 3

c(outer(rep(1, n), 1:n))
## [1] 1 1 1 2 2 2 3 3 3

c(col(diag(n)))
## [1] 1 1 1 2 2 2 3 3 3

最后一站的替代方案 if

以下是第二回合的一些替代方案。第一个假设 n > 1,其他假设 n > 0。在解决方案部分的代码中,我们在 n=3 分支中处理 n=1,因此可以使用以下任何一种。由于下面的第一个替代方案不处理 n=1,它依赖于最后一个if处理 n=1 的第一条腿的事实;但是,下面的其余替代方案可以正确处理 n=1,因此即使我们只有第一条腿处理 n=3,它们也可以使用。

c(1:n, (n-1):1)  # only works for n > 1

c(seq_len(n), rev(seq_len(n-1)))

pmin(seq(2*n - 1), seq(2*n-1, 1))

n - abs((n-1):-(n-1))

推荐阅读