避免在自定义函数中循环

时间:2015-09-08 19:50:36

标签: r loops conventions

我有以下代码执行灵敏度分析:

sensitivity_analysis <- function(stainless_margins, standard_margins,
                                 df_in=all_vals_expanded){
    if (length(stainless_margins) != length(standard_margins)){
        stop("Error: Margin arrays must be of equal length")
    }
    out <- numeric(length(stainless_margins)^2)
    out <- list(x=out, y=out, z=out)
    i <- 1
    for (stainless in stainless_margins){
        df_in <- change_target(target_val=stainless, target_df=df_in,
                               target_shape="straight",
                               target_cat="Stainless - R6")
        for (standard in standard_margins){
            df_in <- change_target(target_val=standard, target_df=df_in,
                                   target_shape="straight",
                                   target_cat="Standard - R6")
            out$x[i] = stainless
            out$y[i] = standard
            out$z[i] = sum(df_in$delta.margin.dollars)
            i <- i + 1
        }
    }
    return(as.data.frame(out))
}

自定义change_target功能如下:

change_target <- function(target_val, target_df, target_shape="straight", target_cat="Standard - R6"){
    target_df$proposed.best.net[target_df$categ == target_cat & target_df$shape
                               == target_shape] <- target_val
    target_df$new.margin.dollars <-
        with(target_df, cost/(1 - proposed.best.net) * (percent.of.list / 100)
             / 0.5364 - cost)

    target_df$delta.margin.dollars <-
        with(target_df, new.margin.dollars - old.margin.dollars)

    target_df$delta.margin.percent.orig <-
        with(target_df, delta.margin.dollars / old.margin.dollars)

    target_df$new.list.price <-
        with(target_df, cost / (1 - proposed.best.net) * (1 / 0.60))

    target_df$list.paid.delta <-
        with(target_df, (percent.of.list / 100) * round((new.list.price -
                                                      list.price), 0))

    target_df$list.paid.delta.percent.orig <-
        with(target_df,list.paid.delta / (list.price * (percent.of.list / 100)))
    target_df$list.paid.delta.percent.orig[is.nan(target_df$list.paid.delta.percent.orig)] <- 0

    return(target_df)
}

有没有办法使用R内置函数,甚至是附加库中的函数,以避免双重for循环,同时仍然保持代码相对简单和可读?此外,是否有一种解决方案可以适用于更通用的情况,比如说我想用四种不同的输入而不是两种输入进行灵敏度分析?

我愿意接受必须修改change_target函数的建议,但宁愿避免这种情况。

0 个答案:

没有答案