【问题标题】:writing a ifelse() on a faster way (with less memory)以更快的方式编写 if else()(内存更少)
【发布时间】:2018-07-10 13:34:18
【问题描述】:

目前,我正在处理一个大数据集。在这个任务中我唯一要做的就是预处理数据。

当我运行我的代码时,我发现我的计算机内存在这行代码中增长得非常快:

binary <- ifelse(subset_variables1 == "0", 0, 1)

该行唯一应该做的就是将我所有的值变成二进制。这可以更快地完成吗?或者这已经是一种很好的方式(我必须处理内存问题)。

【问题讨论】:

  • 如果需要 0/1 或 TRUE/FALSE 输出,则不需要使用 ifelse。只需运行比较本身并使用返回的逻辑向量。
  • binary &lt;- subset_variables1 == "0"
  • 仅供参考,实际上有一个比dplyr更快的ifelseif_else
  • 试试as.integer(subset_variables1 == "0")。将逻辑转换为整数将转换为 1 表示 TRUE 和 0 表示 FALSE。如果你这样做 TRUE * 5FALSE * 5 你会看到区别
  • 并且作为旁注,当转换为逻辑时,除 0 以外的任何整数都被视为 TRUE。你可以试试as.logical(-3:3)

标签: r performance memory


【解决方案1】:

使用布尔类型和/或条件时,您可以将它们与数学运算符一起使用,它们将被解释为10(对于TRUEFALSE)。所以+("0" == 0) 返回11 - ("0" == 0) 返回0

如果你有这样的向量

set.seed(666)
subset_variables1 <- sample(c("0", "1"), 10000, replace = TRUE)

您可以使用1 - (subset_variables1 == "0") 来获得所需的结果。

我已经将它与 cmets 中的一些建议进行了比较,它是最快的。

library(microbenchmark)

microbenchmark(ifelse = ifelse(subset_variables1 == "0", 0, 1),
               as.numeric = as.numeric(subset_variables1),
               if_else = dplyr::if_else(subset_variables1 == "0", 0, 1),
               plus = 1 - (subset_variables1 == "0"),
               times = 1000
)

Unit: microseconds
       expr     min       lq     mean   median       uq      max neval
     ifelse 686.668 701.3440 977.0863 910.6570 1170.816 3222.192  1000
 as.numeric 631.813 642.5910 715.8687 677.3830  720.841 1819.925  1000
    if_else 347.409 377.0665 537.3344 482.7055  657.468 1603.241  1000
       plus  97.170  98.8845 129.9091 107.8545  146.303  741.557  1000

【讨论】:

  • 供您参考:我尝试了您的解决方案。结果:我现在只使用 71% 的内存,而不是使用 98% 的内存(旧解决方案)。
  • 谢谢,很高兴听到这个消息!
  • 一个不错的小技巧:逻辑值向量的平均值是该向量中 TRUE 的比例。
【解决方案2】:

这是一个较慢但更通用的解决方案

v <- rep(1,length(subset_variables1))
v[subset_variables1 =="0"] <- 0

ifelse 用于数字向量,

ifelse_sign <- function(test,yes,no){

    if(length(yes)==1)yes = rep(yes,length(test))
    if(length(no) ==1)no  = rep(no ,length(test))

    yes[!test] <- 0
    no [test]  <- 0

    yes + no + test *0
}

ifelse_sign(subset_variables1=="0",0,1)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    • 1970-01-01
    • 2018-04-18
    • 2010-11-22
    相关资源
    最近更新 更多