Полностью переписан на 2015-11-24, чтобы исправить ошибку в предыдущих версиях.
У вас есть несколько вариантов.
процесс всех целевых столбцов с встроенным вызовом lapply()
, используя :=
для назначения измененных значений на месте. Это полагается на очень удобную поддержку :=
для одновременного назначения нескольким столбцам с именем LHS.
Используйте for
цикл для запуска через целевых столбцов по одному за раз, используя set()
, чтобы изменить значение каждого из них в свою очередь.
Используйте for
цикл для перебора несколько «наивным» называет к [.data.table()
, каждый из которых изменяет один столбец.
Все эти методы кажутся примерно одинаково быстро, поэтому какой из них вы используете, будет быть в основном дело вкуса. (1) красиво компактный и выразительный. Это то, что я чаще всего использую, хотя вы можете найти (2) легче читать. Поскольку они обрабатывают и изменяют столбцы по одному, (2) или (3) будут иметь преимущество в редкой ситуации, когда ваша таблица данных настолько велика, что вы рискуете столкнуться с ограничениями , наложенными вашим R доступной памяти.
library(data.table)
## Create three identical 1000000-by-20 data.tables
DT1 <- data.table(1:1e6,
as.data.table(replicate(1e6, paste(sample(letters, nr, TRUE),
sample(letters, nr, TRUE)))))
cnames <- c("ID", paste0("X", 1:19))
setnames(DT1, cnames)
DT2 <- copy(DT1); DT3 <- copy(DT1)
## Method 1
system.time({
DT1[, cnames[-1] := lapply(DT1[,cnames[-1],with=FALSE],
function(x) gsub(" ", "_", x))]
})
## user system elapsed
## 10.90 0.11 11.06
## Method 2
system.time({
for(cname in cnames[-1]) {
set(DT2, j=cname, value=gsub(" ", "_", DT2[[cname]]))
}
})
## user system elapsed
## 10.65 0.05 10.70
## Method 3
system.time({
for(cname in cnames[-1]) {
DT3[ , cname := gsub(" ", "_", DT3[[cname]]), with=FALSE]
}
})
## user system elapsed
## 10.33 0.03 10.37
Для получения более подробной информации о set()
и :=
, читать их страницу справки, нечестным, набрав ?set
или ?":="
.
Это интересный случай. Здесь 19 столбцов из 20 заменяются; RHS ': =' - это почти вся таблица. Преимущество ': =' больше, когда, скажем, один или два столбца добавляются к 20, или изменяется один или два столбца из 20. В тех случаях большая часть столбцов остается на месте, а ': =' намного быстрее, чем копирование всей таблицы. –
Кроме того, 'set()' - это новая функция в v1.8.0 (еще не включенная в CRAN), которая напрямую выполняет функцию ': ='. 'set()' может быть намного быстрее, чем ': =' при назначении в цикле (для более простого более естественного программирования). В последней новости на домашней странице есть пример. –
@MatthewDowle - Спасибо за ваши комментарии.Они напомнили мне, что в уик-энд у меня появилось ошеломляющее чувство ответа, которое я дал здесь, и подтолкнуло меня к пересмотру. Очевидно, у меня были веские причины чувствовать себя ворчащими. Пожалуйста, взгляните на мой пересмотренный ответ. Также **, пожалуйста, добавьте любые предложения, которые у вас есть в ваших комментариях к тексту моего ответа **, где вы думаете, что они могут помочь. Я посмотрю на 'set()', но пока не чувствую себя готовым обсудить это. И еще раз, спасибо за всю работу, которую вы вложили в продолжение разработки пакета data.table! –