r - 在 R 中构建特定的值组合;改变一个变量保持所有其他变量不变

标签 r combinations permutation

我如何使用 apply()a 开始构建下面的输出 系列或其他函数, b , 和 Change ?我正在寻找一种可以扩展到更多变量的通用方法,而不仅仅是 ab ,如我的示例所示。

输出保持其他变量不变,同时对一个变量应用更改。最终,我正在尝试构建它以进行简单的敏感性分析。我所做的似乎过于复杂。

library(tidyverse)

a <- 10
b <- 100
Change <- seq(-20,20,10)

df3 <- NULL

for (i in a) {
  for (j in b) {
    for (k in Change) {
      df <- data.frame(a_ = i, b_ = j * (1 + k / 100))
      df2 <- data.frame(a_ = i * (1 + k / 100), b_ = j)
      df3 <- bind_rows(df, df2, df3)
    }
  }
}
df3 %>% distinct() %>% arrange(a_)

输出

  a_  b_
1  8 100
2  9 100
3 10 120
4 10 110
5 10 100
6 10  90
7 10  80
8 11 100
9 12 100

最佳答案

通过大量使用 lapplydo.call,此任务可以扩展到 base R 中任意数量的变量。我们还注意到 expand.gridappend 的关键但简单的使用。

specialCombs <- function(myVars, ChangeVec) {
    myLen <- length(myVars) * length(ChangeVec)

    mat <- do.call(rbind, lapply(seq_along(myVars), function(x) {
        staticVar <- lapply(myVars[-x], function(z) {
            lapply(z, rep, length(ChangeVec))
        })

        ## Cartestian Product
        CP <- expand.grid(lapply(lengths(staticVar), seq_len))

        ## Use the cartestian product above (CP) to build all
        ## possible combinations of static columns
        expandStatic <- lapply(1:nrow(CP), function(i) {
            lapply(seq_along(CP[i, ]), function(j) {
                staticVar[[j]][[CP[i, j]]]
            })
        })

        do.call(rbind, lapply(myVars[[x]], function(y) {
            dynVar <- list(y * (1 + ChangeVec / 100))

            ## Place the dynamic vector in the appropriate position
            ## before building a matrix chunk via append and cbind
            do.call(rbind, lapply(expandStatic, function(res) {
                do.call(cbind, append(res, dynVar, after = x - 1))
            }))
        }))
    }))

    mat <- mat[do.call(order, as.data.frame(mat)), ]
    unique(mat)
}

以OP给出的例子:

specialCombs(list(10, 100), Change)
     [,1] [,2]
[1,]    8  100
[2,]    9  100
[3,]   10   80
[4,]   10   90
[5,]   10  100
[6,]   10  110
[7,]   10  120
[8,]   11  100
[9,]   12  100

用更奇特的例子:

specialCombs(list(8:10, 95:100, 150:153, 200:205), Change)
        [,1] [,2] [,3] [,4]
   [1,]  6.4   95  150  200
   [2,]  6.4   95  150  201
   [3,]  6.4   95  150  202
   [4,]  6.4   95  150  203
   [5,]  6.4   95  150  204
   [6,]  6.4   95  150  205
      .    .    .    .    .
      .    .    .    .    .
      .    .    .    .    .
[6907,]   12  100  153  200
[6908,]   12  100  153  201
[6909,]   12  100  153  202
[6910,]   12  100  153  203
[6911,]   12  100  153  204
[6912,]   12  100  153  205

它也更有效率:

OP_code <- function(a, b) {
    df3 <- NULL

    for (i in a) {
        for (j in b) {
            for (k in Change) {
                df <- data.frame(a_ = i, b_ = j * (1 + k / 100))
                df2 <- data.frame(a_ = i * (1 + k / 100), b_ = j)
                df3 <- bind_rows(df, df2, df3)
            }
        }
    }

    df3 %>% distinct() %>% arrange(a_)
}


library(microbenchmark)
microbenchmark(op_code = OP_code(5:15, 85:115),
               new_code = specialCombs(list(5:15, 85:115), Change),
               times = 10, unit = "relative")
Unit: relative
    expr     min       lq     mean   median       uq      max neval
 op_code 73.8084 75.13821 68.30254 69.97878 63.20355 57.79337    10
new_code  1.0000  1.00000  1.00000  1.00000  1.00000  1.00000    10

这是一个非常大的例子:

system.time(test_1 <- OP_code(1:50, 80:180))
 user  system elapsed 
16.91    0.27   17.23 

system.time(test_2 <- specialCombs(list(1:50, 80:180), Change))
user  system elapsed 
0.09    0.01    0.11 

dim(test_1)
[1] 37357     2

## The order is different, so we must sort
identical(unname(as.matrix(
     test_1[do.call(order, test_1), ])), test_2)
[1] TRUE

关于r - 在 R 中构建特定的值组合;改变一个变量保持所有其他变量不变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57677043/

相关文章:

javascript - 在给定 JavaScript 语句的情况下使用 R 下载文件

java - 将 vector 保存在列表中的方法

python - 如何获取字符串所有子串的每一个排列?

r - 在R中合并很多数据帧

r - 如何将表示表达式的字符串传递给 dplyr 0.7 动词?

r - 如何在ggplot2的箱线图中添加每组的观察数和中位数

去编程: Generating Combinations

r - 组合迭代器,如 expand.grid

c# - 您如何按照从最少到最多非零元素的顺序遍历排列?

java - 组合需要第 5 个字符串