R性能提升

时间:2019-10-24 13:06:34

标签: r performance

我想用R解决统计问题。我已经有了一种可行的方法,但是花太多时间才能通过。也许你们中的某人对如何更智能地编程(可能没有循环)有所了解。 有一个字段“订单”。 Orders [,1]包含订单号,而Orders [,2:200]包含按订单排序的商品编号。 我想填写“结果”字段。在Result [,1]中是所有商品编号。要填写的字段是带有商品编号的Result [,2:2:1000],这些商品是与Result [,1]一起购买的。 由于两个循环(i循环和j循环)都超过100000,因此整个过程需要花费……预计约60天。有没有人有提高性能的想法? 我的工作代码是:

for (i in 1:length(Result$Artiklenumber)) {
  for (j in 1:length(Orders$Ordernumber)) {
    if (length(which(Orders[j,]==Result[i,1])) == 0){
      next
    }
    for (k in 2:(min(which(is.na(Orders[j,])))-1) ) { 
      if ( Orders[j,k]!=Result[i,1] ){
        Result[i,min(which(is.na(Result[i,])))] <- Orders[j,k]
      }
    }
  }
}

“订单”示例:

0011566702  10131925    10131927    10136287    10136292    NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
0011677781  16320   16800   16810   18270   18280   807310  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
0011724272  204520  204590  1083740 1083880 1111150 1111640 NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
0011760684  10149459    10149460    10149461    10149462    10149463    10149464    10149465    10149466    10149467    10149468    NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
0011784677  10151542    10151543    10151545    10151549    10151551    10151552    10151555    NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
0011804598  10107450    10123183    NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
0011811507  31540   4028890 NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
0011813716  6670    16800   10050265    NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
0011818851  16800   16810   807310  4229030 10050265    NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA

“结果”示例:

16610   NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
16620   NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
16630   NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
16670   NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
16710   NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
16720   NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
16740   NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
16800   NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
16810   NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
16820   NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA

1 个答案:

答案 0 :(得分:0)

这里是一个没有循环的解决方案。首先,我生成一些小的测试数据:

orders = cbind(1001:1008, matrix(sample(1:6, 8*3, replace=TRUE), 8, 3))
orders[1:2, 4] = orders[4, 3:4] = NA
> orders 
     [,1] [,2] [,3] [,4]
[1,] 1001    2    4   NA
[2,] 1002    2    3   NA
...

然后我提取独特的文章:

articles = unique(as.vector(orders[, -1]))

最后,我创建了一个函数,该函数可以在某个篮子中一起查找文章并将其应用:

findBaskets = function(article) {
  ordersIncludingArticle = apply(orders[, -1] == article, 1, any)
  articlesTogether = unique(as.vector(orders[ordersIncludingArticle, -1]))
  articlesTogether[articlesTogether != article & !is.na(articlesTogether)]
}

sapply(articles, findBaskets)

但是,这以列表格式提供了解决方案:

> res = sapply(articles, findBaskets)
> names(res) = articles
> res 
$`2`
[1] 4 6 3 5 1

$`6`
[1] 3 2 1 5
...

要将其放入数组中,可以创建一个具有正确尺寸的空矩阵,然后用一个循环左右填充该矩阵。这肯定不会损害性能。