【问题标题】:How to optimize runtime for a matrix creation with R?如何使用 R 优化矩阵创建的运行时间?
【发布时间】:2015-11-05 08:54:49
【问题描述】:

我有以下 R 数据框,表示每个国家/地区每个日期(始终在 2015 年和

    type    year    day      p_id   sales   
1   5       2015    144     7115907    2
2   13      2015    108     2339558    1    
3   8       2015    133     362237     1    
4   0       2015    24      2122871    2    
5   0       2015    35      564333     1    
6   10      2015    115     810446     1    
7   5       2015    38      239521     10   
8   12      2015    27      4516049    1    
9   3       2015    85      4352175    1    
10  4       2015    106     132568     2    

我想将这些数据存储在矩阵中。行将是 p_id,列是一年中的某一天(1 到 150)。这是一个例子:

row.names   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96  97  98  99
 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 7115907    0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
 2339558    0   0   0   0   0   1   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   1   0   0   2   1   0   0   1   1   0   2   1   1   1   0   3   1   0   1   1   0   0   0   1   0   1   0   0   1   1   0   1   1   2   2   1   1   1   0   1   1   1   1
  362237    1   1   2   1   1   1   5   1   1   1   0   1   8   1   8   2   1   1   1   1   2   3   1   3   12  4   2   1   1   1   11  2   6   2   2   8   1   6   1   1   1   1   2   1   6   1   7   2   6   1   1   7   1   2   1   3   2   4   1   2   1   4   3   1   2   3   6   1   4   2   3   2   8   1   1   10  1   5   3   4   2   1   1   3   1   1   1   1   1   1   3   1   3   2   1   1   1   1   3
 2122871    1   1   1   1   1   2   0   1   1   1   1   1   1   1   0   2   0   1   1   3   1   2   1   1   3   4   1   3   2   2   3   1   2   1   1   1   2   1   1   2   3   3   1   0   3   1   2   2   4   1   0   1   1   2   1   1   3   2   2   0   2   1   1   1   2   1   4   1   1   1   1   1   1   2   0   1   1   1   0   2   1   1   3   1   1   1   0   1   0   1   1   0   2   1   1   0   4   0   1
  564333    0   0   0   0   0   0   0   0   1   1   2   1   3   1   1   1   1   1   1   5   3   2   1   1   1   1   3   1   1   1   3   1   1   2   1   8   1   1   1   3   1   1   1   1   3   3   1   2   1   5   1   1   8   3   1   3   2   2   4   1   4   4   1   1   1   0   0   1   2   1   1   1   1   0   1   0   1   0   1   1   1   1   0   1   1   1   0   1   1   1   1   2   1   0   1   0   2   4   2
  810446    0   0   0   0   0   0   0   0   1   1   0   1   0   1   0   1   0   0   1   0   1   0   1   1   1   0   1   2   1   1   0   1   1   1   1   0   0   1   1   2   1   1   20  1   1   1   2   3   2   0   1   1   2   1   0   0   1   1   0   0   0   1   1   1   0   0   1   1   1   0   1   1   1   1   1   1   1   0   1   0   1   1   1   1   0   1   1   0   1   1   1   0   1   0   1   1   2   1   1

我有以下代码来生成矩阵。问题是它非常慢。我想加快速度。有可能吗?

# input_data is the first dataframe
generate.matrix = function(input_data){
   days = 150
   p_ids = unique(input_data$p_id)
   mat = data.frame(matrix(rep(0, days*length(p_ids)), ncol=days))
   row.names(mat) <- p_ids
   colnames(mat) <- 1:days
   for(i in 1:nrow(input_data)) {
      row <- input_data[i,]
      mat[row.names(mat) == row$p_id,row$day] = row$sales
   }
   return(mat)
}

【问题讨论】:

  • 我猜你已经可以用mat&lt;-matrix(0,nrow=length(p_ids),ncol=days) 替换mat = data.frame(matrix(rep(0, days*length(p_ids)), ncol=days)),这(根据microbenchmark)对于150*200 矩阵来说要快10 倍
  • 或者你可以使用 reshape2: res
  • 您的输出与您的输入不匹配。您应该发布与您提供的输入完全对应的输出。
  • 重塑功能就像一个魅力。谢谢。

标签: r


【解决方案1】:

要加快代码速度,您应该首先分析您的代码 (have a look here)。

否则,我猜for-loop 会消耗大量时间。用apply 替换循环应该会加快速度。

例如,您可以使用它来代替 for 循环:

sapply(1:nrow(input_data), function(i) {
  row <- input_data[i,]
  mat[row.names(mat) == row$p_id, row$day] <- row$sales
}

但是,使用reshape-family 中的某些东西(如@Heroka 所建议)可能会获得最大的加速,因为这是一个典型的reshape 问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-14
    • 2013-12-09
    • 1970-01-01
    • 1970-01-01
    • 2019-07-11
    • 1970-01-01
    • 2021-09-12
    • 2016-01-13
    相关资源
    最近更新 更多