Эффективно заполненные строки с учетом возможных значений для каждой переменной в R - PullRequest
0 голосов
/ 14 января 2020

У меня есть фрейм данных с 42 переменными, каждая из которых имеет разные возможные значения. Я стремлюсь создать гораздо больший информационный кадр, содержащий строку для каждой возможной комбинации значений для каждой из переменных.

Это будет миллионы строк длинной и слишком большой для хранения в оперативной памяти. Поэтому я пытался создать сценарий, который добавляет каждое возможное значение к существующему файлу. Следующий код работает, но делает это слишком медленно, чтобы быть практичным (также включает в себя только 5 переменных), для запуска на моей машине требуется чуть менее 5 минут.

V1 <- c(seq(0, 30, 1), NA)
V2 <- c(seq(20, 55, 1), NA)
V3 <- c(0, 1, NA)
V4 <- c(seq(1, 16, 1), NA)
V5 <- c(seq(15, 170, 1), NA)


df_empty <- data.frame(V1 = NA, V2 = NA, V3 = NA, V4 = NA)
write.csv(df_empty, "table_out.csv", row.names = FALSE)

start <- Sys.time()
for(v1 in 1:length(V1)){
  V1_val <- V1[v1]

  for(v2 in 1:length(V2)){
    V2_val <- V2[v2]

    for(v3 in 1:length(V3)){
      V3_val <- V3[v3]

      for(v4 in 1:length(V4)){
        V4_val <- V4[v4]

        row <- cbind(V1_val, V2_val, V3_val, V4_val)
        write.table(as.matrix(row), file = "table_out.csv", sep = ",", append = TRUE, quote = FALSE,col.names = FALSE, row.names = FALSE)        
      }
    }
  }
}

print(abs(Sys.time() - start)) # 4.8 minutes
print(paste(nrow(read.csv("table_out.csv")), "rows in file"))

Я протестировал использование data.table::fwrite(), но это не удалось быть быстрее, чем write.table(as.matrix(x)) Я уверен, что у меня проблема с использованием такого количества циклов for, но я не уверен, как перевести это на более эффективный подход.

Спасибо

1 Ответ

1 голос
/ 14 января 2020

Я полагаю, вы можете попробовать следующий код для генерации всех комбинаций

M <- as.matrix(do.call(expand.grid,mget(x = ls(pattern = "^V\\d+"))))

, а затем вы сможете сохранить res в указанном вами файле, например,

write.table(M, file = "table_out.csv", sep = ",", append = TRUE, quote = FALSE,col.names = FALSE, row.names = FALSE)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...