【问题标题】:R Piecewise Function with Multiple Outputs具有多个输出的 R 分段函数
【发布时间】:2016-02-03 01:09:45
【问题描述】:

我有两个函数,每个函数都返回两个值(作为列表)并且在有限域上运行:

# for x >= 0
f <- function(x) { return(list(a=x,b=2*x)) }
# for x < 0
g <- function(x) { return(list(a=x/2,b=x/4)) }

我想做这样的事情:

fg <- function(x) { return(ifelse(x < 0, g(x), f(x))) }

我想得到这个:

> fg(c(1,2))
a$
[1] 1 2
b$
[2] 2 4

> fg(c(-1,-2)
a$
[1] -0.5 -1.0
b$
[2] -0.25 -0.50

相反,我得到了这个:

> fg(c(1,2))
[[1]]
[1] 1 2

[[2]]
[1] 2 4

> fg(c(-1,-2))
[[1]]
[1] -0.5 -1.0

[[2]]
[1] -0.25 -0.50

“$a”和“$b”标签丢失了。

单输入,情况就更糟了:

> fg(1)
[[1]]
[1] 1

我做错了什么?

我怎样才能实现我的目标?

【问题讨论】:

  • 不知道为什么你会收到0。我用 R 3.2.2 得到1。不管怎样,试试x=1; ifelse(x &gt; 0, 1:10, 1:5)。如您所见,ifelse 只返回第一个元素。此时您应该只使用常规的if-loop:fg &lt;- function(x) if ( x &lt; 0) g(x) else f(x)
  • 如果x可以有多个元素,你可以试试:fg &lt;- function(x) sapply(x, function(y) if (y &lt; 0) g(y) else f(y), simplify=FALSE)
  • ifelse 返回一个与 test 形状相同的值.....
  • 我认为最好用适当的样本输入和预期输出来修改问题。

标签: r


【解决方案1】:

我修改了你的代码,

# for x >= 0
f <- function(x) { return(list(a=x,b=2*x)) }
# for x < 0
g <- function(x) { return(list(a=x/2,b=x/4)) }
fg <- function(x) {
    tmp <- lapply(x, function(y) switch(as.character(y > 0), 'TRUE' = f(y), 'FALSE' = g(y)))
    a <- sapply(tmp, function(y) y$a)
    b <- sapply(tmp, function(y) y$b)
    out <- list(a = a, b = b)
    return(out)
}

这是另一个版本,它可以提供您想要的结果,但不需要函数fg。此外,计算是矢量化的:

fg2 <- function(x) {
    list(
        a = x * (1/2)^(x < 0), 
        b = x * 2 * (1/8)^(x < 0)
    )
}

以下是一些例子,

> fg2(1)
$a
[1] 1

$b
[1] 2

> fg2(1:2)
$a
[1] 1 2

$b
[1] 2 4

> fg2(-2:2)
$a
[1] -1.0 -0.5  0.0  1.0  2.0

$b
[1] -0.50 -0.25  0.00  2.00  4.00

【讨论】:

  • 似乎更像是一种“解决方法”。 lapply 调用意味着 f 和 g 函数一次调用一个,而不是传递向量——不是吗?我希望有一个矢量化的解决方案
  • @DavidH 我已经编辑了我的答案,它符合您的要求吗?
猜你喜欢
  • 2020-02-18
  • 2013-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-17
  • 2012-02-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多