简体   繁体   English

R: "if else if" vs "or" 三种情况

[英]R: "if else if" vs "or" with three cases

Im running through some old code to clean it up and saw an old if else if statement that brought up a question in my mind;我运行了一些旧代码来清理它,并看到一个旧的if else if statement在我脑海中提出了一个问题; this is a super simple logic question but for my own edification and to make sure I'm thinking about this logically I wanted to see if a change from the 'old way' to the 'new way', in essence for this case at least, would be the same.这是一个超级简单的逻辑问题,但为了我自己的启迪,并确保我在逻辑上思考这个问题,我想看看是否从“旧方式”转变为“新方式”,至少在本质上对于这种情况,应该是一样的。 My question is: are these two ways of doing this essentially the same?我的问题是:这两种做这件事的方法本质上是一样的吗?

 #old way
df_test = tibble::as_tibble(data.frame(column1 = NA))

if(NROW(df_test$column1) == 0) {
  df_test = TRUE
} else if (all(is.na(df_test$column1))) {
  df_test = TRUE
} else {
  df_test = FALSE
}

#new way
df_test = tibble::as_tibble(data.frame(column1 = NA))

if(NROW(df_test$column1) == 0 | all(is.na(df_test$column1))) {
  df_test = TRUE
} else {
  df_test = FALSE
}

My question is: are these two ways of doing this essentially the same?我的问题是:这两种做这件事的方法本质上是一样的吗?

Yes, they are.对,他们是。

To see this, note that in the first code block, TRUE is returned if either NROW(df_test$column1) == 0 or if all(is.na(df_test$column1)) == TRUE .看到这一点,需要注意的是在第一个代码块, TRUE是,如果返回要么NROW(df_test$column1) == 0或者如果all(is.na(df_test$column1)) == TRUE

Thus, the first if .... else if can be replaced by因此,第一个if .... else if可以被替换为

if(NROW(df_test$column1) == 0 | all(is.na(df_test$column1))) 

and then the 2nd code block immediately follows.然后紧接着是第二个代码块。

Yet another way of doing this:这样做的另一种方法:

df_test = tibble::as_tibble(data.frame(column1 = NA))

df_test <- ifelse(NROW(df_test$column1) == 0 | all(is.na(df_test$column1)), TRUE, FALSE)
df_test 

I believe that this is cleaner...我相信这更清洁......

No, they are not the same不,它们不一样

The reason they're not the same is because the |它们不同的原因是因为| operator always evaluates the operands on both sides.运算符总是计算两边的操作数。 However, in the if(x) else if(y) block, the second if is not evaluated if the first if is true.但是,在if(x) else if(y)块中,如果第一个if为真,则不会评估第二个if The difference is particularly important if the expressions being tested involve side-effects, eg if you are modifying files.如果被测试的表达式涉及副作用,则差异尤其重要,例如,如果您正在修改文件。

Another difference is that |另一个区别是| is vectorised, ie it returns a vector of true/false values if its operands are vectors.被向量化,即如果其操作数是向量,则返回真/假值的向量。 This is usually not what you want in the context of if blocks, and R will throw a warning if a vector of length >1 is returned.if块的上下文中,这通常不是您想要的, if返回长度大于 1 的向量,R 将发出警告。

Simplified example:简化示例:

foo <- function()
{
    print("in foo")
    TRUE
}

bar <- function()
{
    print("in bar")
    TRUE
}

# case 1
if(foo()) x <- 1 else if(bar()) x <- 1

# case 2
if(foo() | bar()) x <- 1

The first case will print out "in foo" only.第一种情况只会打印出"in foo" The second case will print "in foo" followed by "in bar" .第二种情况将打印"in foo"后跟"in bar"

If you want to collapse the if block, use ||如果要折叠 if 块,请使用|| , not | 不是| . . This will only evaluate the right-side operand if the left side is false, and also only returns a scalar value, not a vector.如果左侧为假,这只会评估右侧的操作数,并且也只返回标量值,而不是向量。 This is consistent with how if behaves.这与if行为方式一致。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM