【问题标题】:Loop Taking Too Long to Finish in R循环在 R 中完成时间太长
【发布时间】:2019-11-09 19:13:12
【问题描述】:

我有一些包含 for 循环和嵌套 if 语句的代码。问题是运行时间太长,我想让它更快。

我有一个名为 f2_cebu_davao 的数据框中的群组数据。此数据框中还有一个名为 person_id 的列。同类群组分为 3 类:“基线”、“其他效果”、“广告系列”。

我想遍历 f2_cebu_davao 数据框中的每个 person_id,并检查它在哪个队列中。如果它在队列“基线”或“其他效果”中,那么我将检查 before_baseline_othereffects 表以查看如果可以在该表中找到 ID。如果可以,我在 f2_cebu_davao 表中创建一个新列,该值将“返回”。否则,“新”。

如果群组名称为“campaign”,我将检查 before_campaign 表并执行与上述相同的过程。

我的数据非常大(我所有的对象都很大),所以这需要很长时间才能运行(它已经运行了 30 多分钟,但仍未完成!)。

我怎样才能加快速度(可能通过使用矢量化,或者只是通过稍微修改代码)?

我尝试过循环,但它花费的时间太长。

before_baseline_othereffects <- subset(loans_final_full, submitted_at_date < '2018-05-21')
before_campaign <- subset(loans_final_full, submitted_at_date < '2019-01-21')

for(i in 1:nrow(f2_cebu_davao)){

  if(as.vector(f2_cebu_davao[, 'cohort'][i]) == 'Baseline') {

    if(as.vector(f2_cebu_davao[,'person_id'][i]) %in% as.vector(unique(before_baseline_othereffects$person_id)) == TRUE) {

      f2_cebu_davao$new_or_returning[i] <- 'Returning'

    } else {

      f2_cebu_davao$new_or_returning[i] <- 'New'

    }

  } else if (as.vector(f2_cebu_davao[, 'cohort'][i]) == 'Other Effects'){

     if(as.vector(f2_cebu_davao[,'person_id'][i]) %in% as.vector(unique(before_baseline_othereffects$person_id)) == TRUE) {

      f2_cebu_davao$new_or_returning[i] <- 'Returning'

    } else {

      f2_cebu_davao$new_or_returning[i] <- 'New'

    }



  } else {

    if(as.vector(f2_cebu_davao[,'person_id'][i]) %in% as.vector(unique(before_campaign$person_id)) == TRUE) {

      f2_cebu_davao$new_or_returning[i] <- 'Returning'

    } else {

      f2_cebu_davao$new_or_returning[i] <- 'New'

    }


  }

}

【问题讨论】:

  • 您能提供一些数据和预期的输出吗?

标签: r loops vectorization


【解决方案1】:

如果您可以提供一些示例数据和所需的输出,我们很乐意更新和测试它。我希望这样的事情应该有效。

这里我编了一些假数据:

f2_cebu_davao <- data.frame(stringsAsFactors = F,
  cohort = rep(c("Baseline", "Other Effects", "Something else", 
                 "Another Something"), by = 3),
  person_id = 1:12
)
before_baseline_othereffects <- c(1:4)
before_campaign <- c(5:8)

这里我使用 dplyr 的case_when 应用它,拼出四个案例。这段代码将被矢量化,我希望运行速度比当前循环代码快得多。

  1. 同类群组为“基线”或“其他影响”,并且 person_id 出现在 before_baseline_othereffects 中。这会在第 1 行和第 2 行中创建“返回”。
  2. 鉴于第一个条件未满足,但同类群组仍处于“基线”或“其他影响”中,则返回“新”,如第 5 行和第 6 行中所做的那样。
  3. 鉴于不满足前两个条件,但此人在 before_campaign,标记 Returning,如第 7 行和第 8 行所示。
  4. 否则,请标记“新建”,如第 3 行和第 4 行和第 9-12 行中所示。

library(dplyr)
output <- f2_cebu_davao %>%
  mutate(new_or_returning = case_when(
    cohort %in% c("Baseline", "Other Effects") & 
      person_id %in% before_baseline_othereffects ~ "Returning",
    cohort %in% c("Baseline", "Other Effects")    ~ "New",
    person_id %in% before_campaign                ~ "Returning",
    TRUE                                          ~ "New"
  ))

这是输出:

> output
              cohort person_id new_or_returning
1           Baseline         1        Returning
2      Other Effects         2        Returning
3     Something else         3              New
4  Another Something         4              New
5           Baseline         5              New
6      Other Effects         6              New
7     Something else         7        Returning
8  Another Something         8        Returning
9           Baseline         9              New
10     Other Effects        10              New
11    Something else        11              New
12 Another Something        12              New

【讨论】:

    猜你喜欢
    • 2020-01-25
    • 1970-01-01
    • 2018-11-07
    • 2018-09-20
    • 2016-06-20
    • 1970-01-01
    • 1970-01-01
    • 2017-05-12
    • 1970-01-01
    相关资源
    最近更新 更多