【问题标题】:How would I make this code more compact/efficient?我如何使这段代码更紧凑/更高效?
【发布时间】:2014-04-03 22:20:16
【问题描述】:

对于提出一个简单的问题,我深表歉意,但我第一次尝试学习如何在 R 中使用 for 循环,并且没有太多运气来概括任何指南向我展示的具体问题(或一般而言!)我需要根据专家意见制作很多(~18)不同的分布,并且可以通过将三角形分布相加来做到这一点。但是,代码不是很好,我认为可以使用 for 循环对其进行改进,但我不确定如何 - 特别是因为所有最小/最大/模式估计值都不同。我该如何改进呢? (以下代码仅适用于 18 个发行版之一):

library(mc2d)
x <- seq(from=0.5, to=6, by=0.001)
june.cool <- dtriang(x, min=1,   max=2, mode=1)   +
             dtriang(x, min=1,   max=4, mode=2)   +
             dtriang(x, min=0.5, max=1, mode=1)   +
             dtriang(x, min=2,   max=4, mode=3)   +
             dtriang(x, min=0.25,max=1, mode=1)   +   
             dtriang(x, min=1,   max=3, mode=2)   +
             dtriang(x, min=0.5, max=2, mode=1)   +
             dtriang(x, min=1,   max=5, mode=2.5) +
             dtriang(x, min=1,   max=6, mode=4)

【问题讨论】:

  • @Hugh - 我猜这个包有一个函数:inside-r.org/packages/cran/mc2d/docs/qpert
  • 您应该添加所有包依赖项。
  • 嗨 Hugh - thelatemail 是对的,它是用于建模专家意见的三角形分布的替代方案。我刚刚编辑了问题,因为三角形分布更熟悉。
  • 分布之间的最大/分钟/模式如何变化?这里到底发生了什么变化? x 是否保持不变?
  • 是的——所以对于每个整体分布(在这种情况下,我只展示了一个,“june.cool”),x 应该保持不变。它只是一个从最小值到最大值的任意向量来运行密度函数。每个单独的 dtriang 都有不同的最小/最大/模式,因为这是一位专家对参数的意见。因此,在这种情况下,对于 min=1、max=2 和 mode=1,这是一个人对 6 月份产品冷却所需时间的估计。

标签: r loops


【解决方案1】:

根据@Luca 的回答,我会使用 apply 和 rowSums:

 rowSums(  apply(values, 1, function(args) dtriang(x, min=args[1],
                                                max=args[2],
                                                mode=args[3])
                                        ))

【讨论】:

    【解决方案2】:

    通常最好使用该语言,而不是粘贴在一起并评估的字符串。专家说:

    xprt <- data.frame(min=c(1, 1, .5, 2, .25, 1, .5, 1, 1),
                       max=c(2, 4, 1, 4, 1,3, 2, 5, 6),
                       mode=c(1, 2, 1, 3, 1, 2, 1, 2.5, 4))
    

    您想Map,使用dtriang,将每一行设置为一个新值,并带有一个附加参数(跨行常量)x,所以

    val <- with(xprt, Map(dtriang, min=min, max=max, mode=mode, MoreArgs=list(x=x)))
    

    这给出了一个结果列表,您希望通过将它们相加来将它们减少为单个值

    Reduce(`+`, val)
    

    综合:

    with(xprt, {
        Reduce(`+`, Map(dtriang, min=min, max=max, mode=mode, MoreArgs=list(x=x)))
    })
    

    【讨论】:

    • 嗨 Martin - 你说使用语言工作 - 你到底是什么意思?
    • 您选择的答案会创建一个表示要计算的表达式的字符串,然后对其进行计算。相比之下,@NealFultz 的答案和我的答案直接使用引用您希望转换的值的 符号
    【解决方案3】:

    您可以尝试这样的事情(仅对前三个发行版进行)

    values <- data.frame(min = c(1,1,0.5),
                         max = c(2,4,1),
                         mode = c(1,2,1))
    
    june.cool <- eval(parse(text=paste(apply(values, 1, function(my.row)
                   sprintf("dtriang(x, min=%f, max=%f, mode=%f) ",
                       my.row["min"], my.row["max"], my.row["mode"])),
               collapse = " + ")
    ))
    

    从指定分布参数的data.frame开始,通过单个语句和pasteing一起创建表达式,然后对其求值并将其分配给june.cool

    【讨论】:

    • 这正是我一直在寻找的东西!这里有很多我不认识的命令,所以我会很高兴查找它们:) 我希望我能自己弄清楚如何做到这一点,但我想它会带来更多的 R 经验。谢谢卢卡
    • 我不知道 Map,但我认为 @Neal 的方式肯定比我的好! (是的,我确实喜欢知识分子的诚实 :)))其他时候(例如在 for 循环中),我发现 eval(parse(text=foo)) 技巧很有用
    猜你喜欢
    • 1970-01-01
    • 2011-04-17
    • 2015-01-26
    • 2019-06-29
    • 1970-01-01
    • 2020-10-10
    • 2019-07-28
    • 2015-08-31
    • 2022-01-15
    相关资源
    最近更新 更多