Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用R中的嵌套ifs评估一系列标准-有更好的方法吗?_R_Coding Style_Package_Control Flow - Fatal编程技术网

用R中的嵌套ifs评估一系列标准-有更好的方法吗?

用R中的嵌套ifs评估一系列标准-有更好的方法吗?,r,coding-style,package,control-flow,R,Coding Style,Package,Control Flow,我的大部分工作都是围绕肺结核的诊断测试展开的。正如您所想象的,能够快速评估和验证这些测试的输出非常方便。我写了一个函数,它就是这样做的(为了清晰起见进行了精简)。简而言之,它从测试中获取数值结果,并生成制造商指定的解释 这个函数对我来说运行得很好——我已经通过了数千个测试对它进行了验证,并且它的速度足够快,可以处理任何我抛出的东西。不过,我想将它和几个类似的函数捆绑到一个包中以供更广泛的使用,我想在这样做之前获得一些反馈: 该函数依赖于围绕嵌套if-else函数的大for循环。它并不特别优雅,对

我的大部分工作都是围绕肺结核的诊断测试展开的。正如您所想象的,能够快速评估和验证这些测试的输出非常方便。我写了一个函数,它就是这样做的(为了清晰起见进行了精简)。简而言之,它从测试中获取数值结果,并生成制造商指定的解释

这个函数对我来说运行得很好——我已经通过了数千个测试对它进行了验证,并且它的速度足够快,可以处理任何我抛出的东西。不过,我想将它和几个类似的函数捆绑到一个包中以供更广泛的使用,我想在这样做之前获得一些反馈:

  • 该函数依赖于围绕嵌套if-else函数的大for循环。它并不特别优雅,对()的恐惧无疑会损害我对某些人的信任(嗯哼),但它确实有效。有没有更好的方法?如果是这样的话,保证重新编写有效的代码是否足够好

  • 上述功能中的标准用于解释北美的测试;世界其他地区的标准略有不同。我也想要这些。我正在考虑为每一个单独的、非导出的函数。各种数据检查(从上述要点中排除)将继续存在于主函数中,然后主函数将调用指定的子函数。这听起来合理吗

  • 还有其他建议吗?风格、代码和组织——什么都可以

  • 我意识到我可能应该把这只小鸟推出鸟巢,但我主要是在真空中工作,所以有点紧张。非常感谢您的建议

    编辑:如果你错过了要点的链接



    根据要求,.

    如果您不希望
    用于
    循环,请使用
    应用
    并编写函数以返回解释。

    编辑以反映注释并根据测试数据进行验证

    您可以避免任何类型的循环或
    (如果
    ),只需使用R向量下标:

    qft.interp <- function(nil, tb, mitogen, tbnil.cutoff = 0.35){
    
      # Set a tolerance to avoid floating point comparison troubles.
      tol <- .Machine$double.eps ^ 0.5
    
      # Set up the results vector
      result <- rep(NA, times = length(nil))
      result[nil+tol > 8.0] <- "Indeterminate"
      result[is.na(result) & (tb-nil+tol > tbnil.cutoff) & 
              (tb-nil+tol > .25*nil)] <- "Positive"
      result[is.na(result) & (tb-nil+tol < tbnil.cutoff | tb-nil+tol < .25*nil) &
            !(mitogen-nil+tol < 0.5)] <- "Negative"
      result[is.na(result) & ((tb-nil+tol < tbnil.cutoff | tb-nil+tol < .25*nil) &
              mitogen-nil+tol < 0.5)] <- "Indeterminate"
      result
    }
    
    all(with(tests, qft.interp(nil, tb, mitogen)) == tests$interp)
    
    [1] TRUE
    

    qft.interp
    result[nil+(tol>8.0)]tbnil.cutoff]&(tb-nil+(tol>0.25*nil))]潜在变化的标准是硬编码值,如8、.25等?或术语,例如中间术语?或者别的什么?你能发布一些示例数据和预期结果,这样我们就可以测试我们所做的任何更改吗?事实上,我已经有一段时间没有看过全球标准了——看起来这只是北美独有的最后一组标准(第23-26行)。这将很容易切换开关。但也有可能我想为不同的人群(如免疫功能低下的患者)添加其他标准集,或在研究中制定的替代标准。关于#1,编写良好的for循环通常比
    *apply
    方法更快(for循环在过去版本的R中更慢)。矢量化解决方案将是最快的。谢谢大家的帮助。虽然控制流是一个大问题,但这一问题可能有点过分了。我将进一步研究这个问题,看看是否还有问题。添加了示例数据!谢谢你的建议。我认为你需要删掉一些[I]实例来获得一个完全矢量化的解决方案,但我同意这是最干净的方法。请参阅下面我在评论中的行,这行不通。这种方法的问题是,后面的标准可能会覆盖前面的标准:例如,在样本数据中有一个测试,nil=9.41,tb=6.73,mitogen=10。这是最初设定的(正确的)不确定值,但后来改为负数。原始的
    if()
    流阻止了这种情况的发生。@马特·帕克:您可以将
    is.na(result)
    添加到后面的每个条件中。那么你会保留优先权。@Joshua:的确如此!刚刚在一个更大的数据集上验证了这一点,结果与以前一样。
    apply
    只是
    for
    的一种很好的形式,通常不是快速正确的,这就是为什么我倾向于忘记它。无论如何,速度在这里并不重要——它已经足够快了。不过,相当不错。谢谢你的评论。注意Matt Parker的评论,即标准不是MECE,因此您应该添加
    !将.na(result)
    添加到一些测试中。看看我的最新答案。@Andrie:很好,你已经找到了。我不知道他们是否真的相互排斥。我确实认为收紧代码(如di)将使维护和调试更容易。
    result[ nil + (tol > 8.0)] <- "Indeterminate"
    result[(tb - nil + (tol > tbnil.cutoff) ) & (tb - nil + (tol > .25 * nil) )] <- "Positive"
    result[ (tb - nil + (tol < tbnil.cutoff) )| (tb - nil + (tol < .25 * nil)) &
                             !(mitogen - nil + tol < 0.5) ] <- "Negative"
    result[ (tb - nil + (tol < tbnil.cutoff) ) | (tb - nil + (tol < .25 * nil) ) & 
                              (mitogen - nil + (tol < 0.5) ) ] <- "Indeterminate"