Ответ 1
Попробуйте:
DT = data.table(col1 = 1:3)
colname = "col1"
DT[, colname, with = FALSE] # select
# col1
# 1: 1
# 2: 2
# 3: 3
DT[, (colname) := 4:6] # assign
# col1
# 1: 4
# 2: 5
# 3: 6
Последний известен как столбец plonk, потому что вы заменяете весь вектор столбца ссылкой. Если присутствует подмножество i
, оно будет переназначать по ссылке. Параны вокруг (colname)
- это стенография, введенная в версии v1.9.4 на CRAN Oct 2014. Вот новость:
Using `with = FALSE` with `:=` is now deprecated in all cases, given that wrapping
the LHS of `:=` with parentheses has been preferred for some time.
colVar = "col1"
DT[, colVar := 1, with = FALSE] # deprecated, still works silently
DT[, (colVar) := 1] # please change to this
DT[, c("col1", "col2") := 1] # no change
DT[, 2:4 := 1] # no change
DT[, c("col1","col2") := list(sum(a), mean(b)] # no change
DT[, `:=`(...), by = ...] # no change
См. также раздел Подробности в ?`:=`
:
DT[i, (colnamevector) := value]
# [...] The parens are enough to stop the LHS being a symbol
И чтобы ответить на следующий вопрос в комментарии, здесь один из способов (как обычно, существует много способов):
DT[, colname := cumsum(get(colname)), with = FALSE]
# col1
# 1: 4
# 2: 9
# 3: 15
или вам может быть проще читать, писать и отлаживать только до eval
a paste
, подобно построению динамического оператора SQL для отправки на сервер:
expr = paste0("DT[,",colname,":=cumsum(",colname,")]")
expr
# [1] "DT[,col1:=cumsum(col1)]"
eval(parse(text=expr))
# col1
# 1: 4
# 2: 13
# 3: 28
Если вы так много сделаете, вы можете определить вспомогательную функцию eval
:
EVAL = function(...)eval(parse(text=paste0(...)),envir=parent.frame(2))
EVAL("DT[,",colname,":=cumsum(",colname,")]")
# col1
# 1: 4
# 2: 17
# 3: 45
Теперь, когда data.table
1.8.2 автоматически оптимизирует j
для эффективности, может быть предпочтительнее использовать метод eval
. get()
в j
предотвращает некоторые оптимизации, например.
Или существует set()
. Низкая служебная, функциональная форма :=
, что было бы неплохо. См. ?set
.
set(DT, j = colname, value = cumsum(DT[[colname]]))
DT
# col1
# 1: 4
# 2: 21
# 3: 66