首页 文章

在r中创建一个附加另一个向量的子集的向量

提问于
浏览
0

我有矢量:

c(1,2,3,4,5,6,7,8,9,10)

我想创建矢量:

c(1,2,3,4,5,6,7,8,9,10,2,3,4,5,6,7,8,9,10,3,4,5,6,7,8,9,10,...,8,9,10,9,10)

初始向量的长度是一个更大的数字 .

如果向量内的数字不是1到10怎么办?它们是随机的 . (1..10只是索引)

最好的方法是什么?

2 回答

  • 4

    几种方法

    矩阵

    x <- c(1,2,3,4,5,6,7,8,9,10)
    
    m <- matrix(x, ncol = length(x), nrow = length(x))
    c(x, m[lower.tri(m)])
    
    # [1]  1  2  3  4  5  6  7  8  9 10  2  3  4  5  6  7  8  9 10  3  4  5  6  7  8  9 10  4  5  6  7  8  9 10  5  6  7  8  9 10  6  7  8  9
    # [45] 10  7  8  9 10  8  9 10  9 10 10
    

    如果数字不连续,这也应该有效

    x <- c(1, 3, 9, 12)
    
    m <- matrix(x, ncol = length(x), nrow = length(x))
    c(x, m[lower.tri(m)])
    # [1]  1  3  9 12  3  9 12  9 12 12
    

    Rcpp

    构造矩阵可能很慢,所以这是一种使用 Rcpp 的方法

    library(Rcpp)
    
    cppFunction('Rcpp::NumericVector expandVec(Rcpp::NumericVector x) {
      Rcpp::IntegerVector len = seq(1, x.size());
      int n = std::accumulate(len.begin(), len.end(), 0.0);
      Rcpp::NumericVector res(n);
      int counter = 0;
      for (int i = 0; i < x.size(); i++) {
        for (int j = i; j < x.size(); j++) {
          res[counter] = x[j];
          counter++;
        }
      }
      return res;
    }')
    
    expandVec(x)
    # [1]  1  3  9 12  3  9 12  9 12 12
    

    基准测试

    x <- 1:10000
    
    library(microbenchmark)
    microbenchmark(
        mat = {
            m <- matrix(x, ncol = length(x), nrow = length(x))
            c(x, m[lower.tri(m)])
        },
        sap = {
            unlist(sapply(seq_along(x), function(i) x[i:length(x)]))
        },
        rcpp = {
            expandVec(x)
        },
        times = 5
    )
    
    
    # Unit: milliseconds
    # expr       min        lq      mean    median        uq       max neval
    #  mat 4162.9725 4203.3983 4244.7126 4236.7377 4301.8310 4318.6233     5
    #  sap  571.1738  605.8128  621.1055  625.9673  642.3775  660.1963     5
    # rcpp  317.2585  331.1198  355.9293  335.0221  383.9853  412.2611     5
    
  • 4

    EDIT

    如果向量不连续,那么我们可以这样做:

    x <- c(1, 3, 9, 12)
    unlist(sapply(seq_along(x), function(i) x[i:length(x)]))
    
    #[1]  1  3  9 12  3  9 12  9 12 12
    

    这也适用于连续的载体

    x <- c(1,2,3,4,5,6,7,8,9,10)
    unlist(sapply(seq_along(x), function(i) x[i:length(x)]))
    
    #[1]   1  2  3  4  5  6  7  8  9 10  2  3  4  5  6  7  8  9 10  3  4  5  6  7  8
    #[26]  9 10  4  5  6  7  8  9 10  5  6  7  8  9 10  6  7  8  9 10  7  8  9 10  8
    #[51]  9 10  9 10 10
    

    Original Answer

    应该有一些简单但现在我能想到的是:

    unlist(sapply(x, function(i) seq(i, max(x))))
    
    #[1]   1  2  3  4  5  6  7  8  9 10  2  3  4  5  6  7  8  9 10  3  4  5  6  7  8
    #[26]  9 10  4  5  6  7  8  9 10  5  6  7  8  9 10  6  7  8  9 10  7  8  9 10  8
    #[51]  9 10  9 10 10
    

    在这里,我们遍历 x 中的每个元素,并从该元素创建一个序列,直到向量中的 max .

    data

    x <- c(1,2,3,4,5,6,7,8,9,10)
    

相关问题