首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在非向量化的情况下是否合适,反之亦然?

在非向量化的情况下是否合适,反之亦然?
EN

Stack Overflow用户
提问于 2011-11-18 23:10:33
回答 2查看 566关注 0票数 9

(背景信息:ifelse评估这两个表达式,尽管只返回一个表达式。编辑:这是一个不正确的声明。见汤米的答覆)

在非向量化的情况下使用ifelse有意义吗?我认为,“可读性”可能是一个有效的答案,当我们不关心小的效率收益,但除此之外,它是否更快/等效/更好的一些-其他方式使用ifelse时,一个if,然后else将完成这项工作?

同样,如果我有向量化的情况,那么ifelse总是最好的工具吗?这两个表达式都被计算出来,这似乎很奇怪。一个一个地循环,然后做一个正常的if,然后做一个else,这样会更快吗?我想,只有当评估表达式花费了很长时间的时候,这才有意义。还有其他不涉及显式循环的替代方案吗?

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-11-18 23:23:26

首先,ifelse而不是总是计算这两个表达式--只有在测试向量中同时有TRUEFALSE元素的情况下。

代码语言:javascript
复制
ifelse(TRUE, 'foo', stop('bar')) # "foo"

在我看来:

ifelse应该在非向量化的情况下使用而不是。在if / else上使用if总是更慢,而且更容易出错

代码语言:javascript
复制
# This is fairly common if/else code
if (length(letters) > 0) letters else LETTERS

# But this "equivalent" code will yield a very different result - TRY IT!
ifelse(length(letters) > 0, letters, LETTERS)

然而,在向量化的情况下,ifelse可能是一个很好的选择--但是请注意,结果的长度和属性可能不是您所期望的(正如上面所述,我认为ifelse在这方面是坏的)。

下面是一个例子:tst的长度为5,并且有一个类。我希望结果是长度为10,没有类,但这不是发生的-它得到一个不兼容的类和长度5!

代码语言:javascript
复制
# a logical vector of class 'mybool'
tst <- structure(1:5 %%2 > 0, class='mybool')

# produces a numeric vector of class 'mybool'!
ifelse(tst, 101:110, 201:210)
#[1] 101 202 103 204 105
#attr(,"class")
#[1] "mybool"

为什么我会期望长度是10?因为R“循环”中的大多数函数匹配的向量越短,匹配的时间越长:

代码语言:javascript
复制
1:5 + 1:10 # returns a vector of length 10.

...But ifelse只循环yes/no参数以匹配tst参数的长度。

为什么我希望从测试对象中复制类(和其他属性),而不是,而不是?因为返回逻辑向量的<不从其(通常为数字)参数复制类和属性。它不会这样做,因为它通常是非常错误的。

代码语言:javascript
复制
1:5 < structure(1:10, class='mynum') # returns a logical vector without class

最后,“自己动手”能更有效吗?嗯,ifelse似乎不是像if那样的原语,它需要一些特殊的代码来处理NA。如果您没有NA,那么您自己就可以更快地完成它。

代码语言:javascript
复制
tst <- 1:1e7 %%2 == 0
a <- rep(1, 1e7)
b <- rep(2, 1e7)
system.time( r1 <- ifelse(tst, a, b) )            # 2.58 sec

# If we know that a and b are of the same length as tst, and that
# tst doesn't have NAs, then we can do like this:
system.time( { r2 <- b; r2[tst] <- a[tst]; r2 } ) # 0.46 secs

identical(r1, r2) # TRUE
票数 15
EN

Stack Overflow用户

发布于 2011-11-19 01:57:55

关于你的第二点,你是如何定义“最佳”的?我认为ifelse()是更易读的解决方案之一,但可能并不总是最快的。具体来说,我发现写出布尔条件并将它们相加可以给您带来一些性能上的好处。下面是一个简单的例子:

代码语言:javascript
复制
> x <- rnorm(1e6)
> system.time(y1 <- ifelse(x > 0,1,2))
   user  system elapsed 
   0.46    0.08    0.53 
> system.time(y2 <- (x > 0) * 1 + (x <= 0) * 2)
   user  system elapsed 
   0.06    0.00    0.06 
> identical(y1, y2)
[1] TRUE

因此,如果速度是您最关心的,布尔方法可能会更好。然而,就我的大部分目的而言,我发现ifelse()足够快,而且很容易摸索。你的里程可能会有明显的变化。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8190279

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档