Когда мне следует использовать оператор: = в data.table?

88

data.tableтеперь у объектов есть оператор: =. Что отличает этот оператор от всех других операторов присваивания? Кроме того, каково его использование, насколько он быстрее и когда его следует избегать?

Ари Б. Фридман
источник

Ответы:

94

Вот пример сокращения 10 минут до 1 секунды (из НОВОСТЕЙ на домашней странице ). Это похоже на подчиненное назначение, data.frameно не копирует каждый раз всю таблицу.

m = matrix(1,nrow=100000,ncol=100)
DF = as.data.frame(m)
DT = as.data.table(m)

system.time(for (i in 1:1000) DF[i,1] <- i)
     user  system elapsed 
  287.062 302.627 591.984 

system.time(for (i in 1:1000) DT[i,V1:=i])
     user  system elapsed 
    1.148   0.000   1.158     ( 511 times faster )

Если собрать :=в jподобных позволяет более идиомы:

DT["a",done:=TRUE]   # binary search for group 'a' and set a flag
DT[,newcol:=42]      # add a new column by reference (no copy of existing data)
DT[,col:=NULL]       # remove a column by reference

а также :

DT[,newcol:=sum(v),by=group]  # like a fast transform() by group

Я не могу придумать причин, которых следует избегать :=! Кроме внутри forцикла. Поскольку :=появляется внутри DT[...], это связано с небольшими накладными расходами [.data.tableметода; например, S3 отправка и проверка на наличие и тип аргументов , такие как i, by, и nomatchт.д. Таким образом , для внутренних forпетель, есть низкие накладные расходы, прямой вариант :=называется set. Смотрите ?setболее подробную информацию и примеры. Недостатки setinclude в том, что это iдолжны быть номера строк (без двоичного поиска), и их нельзя комбинировать с by. Эти ограничения setмогут значительно снизить накладные расходы.

system.time(for (i in 1:1000) set(DT,i,"V1",i))
     user  system elapsed 
    0.016   0.000   0.018
Мэтт Доул
источник
26
Спасибо за разработку этого пакета. У меня такое чувство, что я собираюсь пересмотреть большую часть своего кода, чтобы использовать этот пакет.
Итератор
1
В чате меня попросили задать себе вопрос / ответить (что, по-видимому, поощряется ) - этот вопрос здесь
Мэтт Доул
4
@MatthewDowle Хотите включить объяснение, когда не использовать: = и вместо этого использовать set ()?
Ари Б. Фридман
2
@MatthewDowle Я бы снова +1, если бы мог.
Ари Б. Фридман
3
@jabberwocky Нет проблем. set(DT, i, "V1", i)устанавливает "V1"столбец, в то время как set(DT, i, colVar, i)задает имя столбца, содержащееся в colVarпеременной (например, если это colVar = "V1"было сделано ранее). Кавычки указывают на то, что имя столбца следует воспринимать буквально, а не искать переменную.
Мэтт Доул