Как получить лучшую производительность в R: один большой файл или несколько меньших файлов? - PullRequest
0 голосов
/ 18 октября 2018

У меня было около 200 различных файлов (все они были большими матрицами, 465x1080) (это огромно для меня).Затем я использовал cbind2, чтобы сделать их все одной большей матрицей (465x200000).

Я сделал это, потому что мне нужно было создать один отдельный файл для каждой строки (465 файлов), и я подумал, что это будет легче дляR загрузить данные из 1 файла в память только ОДИН РАЗ, а затем просто прочитать строку в строке, создав отдельный файл для каждого из них, вместо того, чтобы открывать и закрывать 200 разных файлов для каждой строки.

Это действительно более быстрый путь?(Мне интересно, потому что сейчас для этого требуется довольно много).Когда я проверяю в диспетчере задач из Windows, он показывает объем оперативной памяти, используемой R, и он все время идет от 700 МБ до 1 ГБ до 700 МБ (дважды в секунду).Похоже, что основной файл не был загружен только один раз, но он загружается и стирается из памяти на каждой итерации (что может быть причиной того, что он немного медленный?).

Я новичок, поэтому все, что я написал, может не иметь никакого смысла.

Вот мой код: (эти +1 и -1, потому что исходные данные имеют 1 дополнительный столбецчто мне не нужно в новых файлах)

extractStationData <- function(OriginalData, OutputName = "BCN-St") {

for (i in 1:nrow(OriginalData)) {

    OutputData <- matrix(NA,nrow = ncol(OriginalData)-1,3)
    colnames(OutputData) <- c("Time","Bikes","Slots")

    for (j in 1:(ncol(OriginalData)-1)) {

        OutputData[j,1] <- colnames(OriginalData[j+1])
        OutputData[j,2] <- OriginalData[i,j+1]

    }

    write.table(OutputData,file = paste(OutputName,i,".txt",sep = ""))
    print(i)

}

}

Есть мысли?Может быть, я должен просто создать объект (огромный файл) перед первым циклом for, а затем он будет загружен только один раз?

Заранее спасибо.

1 Ответ

0 голосов
/ 18 октября 2018

Предположим, что вы уже создали матрицу 465x200000, и речь идет только о функции extractStationData.Затем мы можем изменить его, например, следующим образом:

require(data.table)
extractStationData <- function(d, OutputName = "BCN-St") {
  d2 <- d[, -1] # remove the column you do not need
  # create empty matrix outside loop:
  emtyMat <- matrix(NA, nrow = ncol(d2), 3)
  colnames(emtyMat) <- c("Time","Bikes","Slots")
  emtyMat[, 1] <- colnames(d2)
  for (i in 1:nrow(d2)) {
    OutputData <- emtyMat
    OutputData[, 2] <- d2[i, ]
    fwrite(OutputData, file = paste(OutputName, i, ".txt", sep = "")) # use fwrite for speed
  }
}

V2:

Если ваш OriginalData находится в матричном формате, этот подход для создания списка новых data.tables выглядит довольно быстро:

extractStationData2 <- function(d, OutputName = "BCN-St") {
  d2 <- d[, -1] # romove the column you dont need
  ds <- split(d2, 1:nrow(d2))
  r <- lapply(ds, function(x) {
    k <- data.table(colnames(d2), x, NA)
    setnames(k, c("Time","Bikes","Slots"))
    k
  })
  r
}
dl <- extractStationData2(d) # list of new data objects
# write to files:
for (i in seq_along(dl)) {
  fwrite(dl[[i]], file = paste(OutputName, i, ".txt", sep = ""))
  }

Должно работать и для data.frame с небольшими изменениями: k <- data.table(colnames(d2), t(x), NA)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...