Прежде всего, следует полностью развеять миф о том, что lapply
в любом случае быстрее, чем эквивалентный код, использующий for loop
. В течение многих лет это было исправлено, и for loops
в любом случае должен быть быстрее, чем эквивалентный lapply
.
Я буду визуализировать использование for loop
, так как вам кажется, что это более интуитивно понятно. Однако обратите внимание, что я работаю в основном в T-sql, и может потребоваться некоторое преобразование.
n <- 1e5
outputDat <- vector('list', n)
for (i in 1:10000){
id <- element_a[i]
location <- element_b[i]
language <- element_c[i]
date_creation <- element_d[i]
df <- data.frame(id, location, language, date_creation)
colnames(df) <- c("id", "location", "language", "date_creation")
outputDat[[i]] <- df
}
## Combine data.frames
outputDat <- do.call('rbind', outputDat)
#Write the combined data.frame into the database.
##dbBegin(con) #<= might speed up might not.
dbWriteTable(con, "my_database", df, append = TRUE, row.names = FALSE)
##dbCommit(con) #<= might speed up might not.
Используя Transact-SQL, вы также можете объединить всю строку в один оператор insert into
. Здесь я отклонюсь и буду использовать apply
для перебора строк, так как в этом случае это гораздо более читабельно. Цикл for снова работает так же быстро, если все сделано правильно.
#Create the statements. here
statement <- paste0("('", apply(outputDat, 1, paste0, collapse = "','"), "')", collapse = ",\n") #\n can be removed, but makes printing nicer.
##Optional: Print a bit of the statement
# cat(substr(statement, 1, 2000))
##dbBegin(con) #<= might speed up might not.
dbExecute(con, statement <- paste0(
'
/*
SET NOCOCUNT ON seems to be necessary in the DBI API.
It seems to react to 'n rows affected' messages.
Note only affects this method, not the one using dbWriteTable
*/
--SET NOCOUNT ON
INSERT INTO [my table] values ', statement))
##dbCommit(con) #<= might speed up might not.
Обратите внимание, как я комментирую, это может просто привести к неправильной загрузке таблицы, поскольку пакет DBI
, кажется, иногда не может выполнить транзакцию такого типа, если это приводит к одному или нескольким сообщениям о n rows affected
.
И последнее, но не менее важное: после того, как операторы сделаны, их можно скопировать и вставить из R
в любой графический интерфейс, который напрямую обращается к базе данных, используя, например, writeLines(statement, 'clipboard')
или записывая в текстовый файл (файл более стабилен, если ваши данные содержат много данных). ряды). В редких исключительных случаях это последнее средство может быть быстрее, если по какой-либо причине DBI
или альтернативные R
пакеты работают слишком медленно без причины. Поскольку это похоже на личный проект, этого может быть достаточно для вашего использования.
person
Oliver
schedule
05.11.2019
for
следует избегать любой ценой, и рекомендуется использовать циклыlapply
. - person Parfait   schedule 05.11.2019