如何使用rbind()优化此R代码?

时间:2018-01-14 17:28:05

标签: r optimization

这是我的代码摘录(为简洁起见):

sample.faktisktdata <- function(n) {
    Ntriangeldata <- Ndata[sample(nrow(Ndata), n, replace=TRUE),]
    faktiskt.data <- data.frame()

    for (i in 1:n) {
        faktiskt.data <- rbind(faktiskt.data,
                               faktisktdata[faktisktdata$NR %in% Ntriangeldata$NR[i],])
    }

    # ...
}

当使用n = 2000调用时,此函数sample.faktisktdata在我的机器上运行大约5秒钟。我相信罪魁祸首是调用rbind的for循环。我知道在for循环中使用rbind的速度非常慢,而且我花了好几个小时试图找出如何以更优化的方式重写它,但我已经卡住了。

我试过的一种方法是创建一个预先分配的带有20,000行的data.frame,然后逐行填充它。由于某种原因,结果变慢了(大约慢了3倍)。看起来像这样:

sample.faktisktdata <- function(n) {
    Ntriangeldata <- Ndata[sample(nrow(Ndata), n, replace=TRUE), ]

    faktiskt.data <- data.frame(matrix(ncol=13, nrow=20000))
    colnames(faktiskt.data) <- colnames(faktisktdata)
    count <- 0

    for (i in 1:n) {
        dataToInsert <- faktisktdata[faktisktdata$NR %in% Ntriangeldata$NR[i],]

        if (nrow(dataToInsert) > 0) {
            for (j in 1:nrow(dataToInsert)) {
                faktiskt.data[count,] <- dataToInsert[j,]
                count <- count + 1
            }
        }
    }

    // ...
}

来自Ndata的一些示例行(包含总共4738行,我为瑞典列名称道歉):

> Ndata[1:5,]
          NR skadedatum rapportdatum  slutdatum betaldatum utbetalning  totalut reserv regress skadekostnad skadeår rapportår
2  000002-16 2013-12-03   2016-01-15 2016-11-02 2016-06-20    4126.304 47147.64      0       0     47147.64    2013      2016
9  000004-16 2014-04-25   2016-01-05 2016-03-03 2017-01-12    5644.361  6276.00  34037       0     40313.00    2014      2016
12 000005-15 2014-04-11   2015-01-07 2016-03-02 2015-02-20   11468.442 36060.00      0       0     36060.00    2014      2015
22 000008-14 2013-01-31   2014-01-14 2014-06-10 2014-03-11    9482.826 55215.00      0       0     55215.00    2013      2014
27 000008-15 2014-09-09   2015-01-08 2015-08-19 2015-05-13    3556.742 18500.00  10000       0     28500.00    2014      2015

来自faktisktdata的一些示例行(包含总共22,885行):

> faktisktdata[1:5,]
          NR skadedatum rapportdatum  slutdatum betaldatum utbetalning  totalut reserv regress skadekostnad skadeår betalår rapportår
2  000002-16 2013-12-03   2016-01-15 2016-11-02 2016-06-20   4126.3044 47147.64      0       0     47147.64    2013    2016      2016
3  000002-16 2013-12-03   2016-01-15 2016-11-02 2016-06-27  40195.0597 47147.64      0       0     47147.64    2013    2016      2016
4  000002-16 2013-12-03   2016-01-15 2016-11-02 2016-11-03   2700.0594 47147.64      0       0     47147.64    2013    2016      2016
12 000005-15 2014-04-11   2015-01-07 2016-03-02 2015-02-20  11468.4415 36060.00      0       0     36060.00    2014    2015      2015
13 000005-15 2014-04-11   2015-01-07 2016-03-02 2015-03-09    705.5974 36060.00      0       0     36060.00    2014    2015      2015

目标是从NR中名为Ndata的列中替换2,000个观察结果。对于从Ndata采样的每个元素,我想从faktisktdata中提取具有相同NR的所有行。因此,如果从Ndata提取两次相同的值,我希望faktisktdata对应于该值的所有行在我的结果数据结构中出现两次。

任何人都可以帮助我或提供任何指示吗?我将非常感激。

1 个答案:

答案 0 :(得分:1)

我建议使用lapplydata.table&#39; s rbindlist。代码看起来像这样:

sample.faktisktdata2 <- function(n) {
  require(data.table)
  Ntriangeldata <- Ndata[sample(nrow(Ndata), n, replace=TRUE),]
  faktiskt.data <- data.frame()

  dtList <- lapply(1:n, function(x) {
      faktisktdata[faktisktdata$NR %in% Ntriangeldata$NR[x],]
    }
  )
  faktiskt.data <- rbindlist(dtList, use.names = T, fill = T)
  faktiskt.data
}