R 使用多个条件的if语句更好还是使用更多的else if语句更好?

R 使用多个条件的if语句更好还是使用更多的else if语句更好?,r,if-statement,runtime,R,If Statement,Runtime,我是数学家,所以我对它了解不多。我想知道使用多个条件的语句是否更快,或者使用更多的if/else if语句是否更快,如下面的示例所示。 考虑到我有一个很大的数据表(有数百万行),在函数中有这个if语句,我应用到一列中的每一行,结果存储在新列中。我只是想知道这两种方法之间是否有一些区别(更快/更慢/相同) if (is.na(numerator) == TRUE){ result = 0 } else if (numerator == 0){ re

我是数学家,所以我对它了解不多。我想知道使用多个条件的语句是否更快,或者使用更多的if/else if语句是否更快,如下面的示例所示。 考虑到我有一个很大的数据表(有数百万行),在函数中有这个if语句,我应用到一列中的每一行,结果存储在新列中。我只是想知道这两种方法之间是否有一些区别(更快/更慢/相同)

    if (is.na(numerator) == TRUE){
        result = 0
    }  else if (numerator == 0){
        result = 0
    }  else if (is.na(denominator) == TRUE){
        result = max
    }  else if (denominator == 0){
        result = max
    }  else {
        result = numerator/denominator
    }

Hy

为了改进上面的代码形式,我建议您首先使用if语句,这将是最常见的。这将使代码速度加快一点,因为在大多数情况下,if-else区域直到最后才被检查。我做了一个非常小的测试:

df <- data.frame(check = sample(c(0,1),size = 10000, replace = T, prob = c(0.1,0.9)),
                 solution = rep(NA, 10000))

start_t <- Sys.time()
for (idx in seq_len(nrow(df))) {
  if(df[idx, "check"]==0) {
    df[idx, "solution"] <- "zero"
  } else if (df[idx, "check"]==1) {
    df[idx, "solution"] <- "one"
  }
}
print(Sys.time()-start_t)

此代码只需
0.6977119秒的时差
。它的速度提高了约8%,并且完成了与上述示例相同的工作。希望你明白我的意思,祝你的代码好运。

让我们做一个简单的实验

虚拟数据
数据从逻辑上讲,这两个版本是相同的,我也不期望性能会有太大差异。我这样说是因为对于给定的一组条件,两个版本都需要运行相同数量的逻辑检查。所以…使用你觉得更可读的版本。我将使用第二个版本,因为每个
结果
结果都与导致该结果的所有条件相结合。对于初学者来说,不需要执行
is.na(分子)=TRUE
is.na(分子)
已经返回真/假值。好的,谢谢@Timbiegeleisen也许%
中的
match
%in%
适用于这里?嘿,这里有两个答案。两种观点是不同的。那么,哪一种观点或哪一种观点没有抓住你的问题?
df <- data.frame(check = sample(c(0,1),size = 10000, replace = T, prob = c(0.1,0.9)),
                 solution = rep(NA, 10000))

start_t <- Sys.time()
for (idx in seq_len(nrow(df))) {
  if(df[idx, "check"]==0) {
    df[idx, "solution"] <- "zero"
  } else if (df[idx, "check"]==1) {
    df[idx, "solution"] <- "one"
  }
}
print(Sys.time()-start_t)
df <- data.frame(check = sample(c(0,1),size = 10000, replace = T, prob = c(0.1,0.9)),
                 solution = rep(NA, 10000))

start_t <- Sys.time()
for (idx in seq_len(nrow(df))) {
  if(df[idx, "check"]==1) {
    df[idx, "solution"] <- "one"
  } else if (df[idx, "check"]==0) {
    df[idx, "solution"] <- "zero"
  }
}
print(Sys.time()-start_t)
data <- data.frame(numerator = sample(c(0:9, NA), 10000, replace = T),
                   denominator = sample(c(0:9, NA), 10000, replace = T))
f1 <- function(x){
  num <- x[1] ; denom <- x[2]
  if (is.na(num)){
    result = 0
  }  else if (num == 0){
    result = 0
  }  else if (is.na(denom)){
    result = Inf
  }  else if (denom == 0){
    result = Inf
  }  else {
    result = num / denom
  }
  return(result)
}

f2 <- function(x){
  num <- x[1] ; denom <- x[2]
  if (is.na(num) || num == 0){
    result = 0
  }  else if (is.na(denom) || denom == 0){
    result = Inf
  }  else {
    result = num / denom
  }
  return(result)
}
library(microbenchmark)
library(ggplot2)

res <- microbenchmark(
  type1 = {
    quotient1 <- apply(data, 1, f1)
  }, type2 = {
    quotient2 <- apply(data, 1, f2)
  }, times = 100
)

res
# Unit: milliseconds
#  expr      min       lq     mean   median       uq       max
# type1 21.91925 23.70445 27.16314 25.52339 26.90110 122.91710
# type2 22.00139 23.64297 26.11080 25.04576 26.46136  42.62506

autoplot(res)