r - R 数据表中较慢的 ifelse 的替代方案

标签 r performance if-statement data.table

我正在编写一个函数,其中多个 ifelse 用于数据表操作。虽然我使用数据表来提高速度,但多个 ifelse 使我的代码变慢,并且此功能适用于大型数据集。因此我想知道是否有 iflese 的替代品。
函数中的一个示例 iflese(有接近 15 个 iflese ),在此示例中,如果 x 为空,则标志设置为 1,否则为 0。

    dt<-dt[,flag:=ifelse(is.na(x)|!nzchar(x),1,0)]

最佳答案

最快的方法可能取决于您的数据是什么样的。评论中提到的那些都可以与此示例进行比较:

(@DavidArenburg 提到了 twice;@akrun 提到了 onceadd。我不确定如何使用 replications > 1 对这些进行基准测试,因为这些对象实际上是在基准测试期间修改的。)

DT <- data.table(x=sample(c(NA,"",letters),1e8,replace=TRUE))

DT0 <- copy(DT)
DT1 <- copy(DT)
DT2 <- copy(DT)
DT3 <- copy(DT)
DT4 <- copy(DT)
DT5 <- copy(DT)
DT6 <- copy(DT)
DT7 <- copy(DT)

library(rbenchmark)
benchmark(
ifelse  = DT0[,flag:=ifelse(is.na(x)|!nzchar(x),1L,0L)],
keyit   = {
    setkey(DT1,x)   
    DT1[,flag:=0L]
    DT1[J(NA_character_,""),flag:=1L]
},
twiceby = DT2[, flag:= 0L][is.na(x)|!nzchar(x), flag:= 1L,by=x],
twice   = DT3[, flag:= 0L][is.na(x)|!nzchar(x), flag:= 1L],
onceby  = DT4[, flag:= +(is.na(x)|!nzchar(x)), by=x],
once    = DT5[, flag:= +(is.na(x)|!nzchar(x))],
onceadd = DT6[, flag:= (is.na(x)|!nzchar(x))+0L],
oncebyk = {setkey(DT7,x); DT7[, flag:= +(is.na(x)|!nzchar(x)), by=x]},
replications=1
)[1:5]
#      test replications elapsed relative user.self
# 1  ifelse            1   19.61   31.127     17.32
# 2   keyit            1    0.63    1.000      0.47
# 6    once            1    3.26    5.175      2.68
# 7 onceadd            1    3.24    5.143      2.88
# 5  onceby            1    1.81    2.873      1.75
# 8 oncebyk            1    0.91    1.444      0.82
# 4   twice            1    3.17    5.032      2.79
# 3 twiceby            1    3.45    5.476      3.16

讨论。在本例中,keyit是最快的。但是,它也是最冗长的,它改变了表格的排序。另外,keyit对 OP 的问题非常具体(利用正好两个字符值符合条件 is.na(x)|!nzchar(x) 的事实),因此对于其他应用程序可能不是那么好,因为它需要编写类似的东西
keyit   = {
    setkey(DT1,x)
    flagem = DT1[,some_other_condition(x),by=x][(V1)]$x
    DT1[,flag:=0L]
    DT1[J(flagem),flag:=1L]
}

关于r - R 数据表中较慢的 ifelse 的替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30980545/

相关文章:

r - 导出具有负刻度线长度的图时,轴标签会碰到轴 (ggplot2)

r - 如何阻止 R 离开僵尸进程

R,如何创建一个有空格的数字序列?

c++ - 任何快速有效的方式来生成 3D 网格?

ruby - 带有 Ruby 的 XML 数据扫描器 : case statement or dynamic dispatch in term of performance?

c# - 如何在 If 语句中评估 Enum?

从 Powershell 运行 R 脚本

java - JTable 调用自定义单元格渲染器方法...连续

java - 在检查用户输入的字母时避免 26 if/elseif/else 语句

php - 某些语言中 elseif 或 elif 语句背后的基本原理