Repository navigation
Internal error: DT passed to assign has not been allocated enough column slots #4100
Description
Activity
This is still an issue in
1.14.8:Here is a mini-example for a unit test:
# options('datatable.alloccol' = 1024L) df <- data.table::data.table(x = 1) for (i in 1:2000) data.table::set(df, j = as.character(i), value = 1) # Error in data.table::set(df, j = as.character(i), value = 1) : # Internal error: DT passed to assign has not been allocated enough column slots. l=1025, tl=1025, adding 1
Adjusting
datatable.alloccolresolves the issue.setalloccolis executed at the end ofdata.table()with default argument fromoptions('datatable.alloccol').Would adding
alloccolas an argument todata.table()be a viable option, as a way to override the default? This would also draw attention to the relevant documentation as requested in #1831.Currently, one has two options: either adjust global
optionsbefore making a DT, or executesetalloccolagain on the created DT.Reacted by Jason Poulos and Noskario- addedtop requestOne of our most-requested issuesOne of our most-requested issues
on Apr 14, 2024 Will this be fixed at some point? If not, what would be the recommended way to deal with that?
Probably that in scenarios likefor (i in 1:2000) data.table::set(df, j = as.character(i), value = 1)you should use:=instead?
Likefor (i in 1:2000) df[,:=(colname = 1), env = list(colname = as.character(i))]
It is a bit strange that in the documentation it says thatsetwould be "appropriate for use inside a for loop" when in fact only:=works in a for loop (at least in this scenario)Probably that in scenarios like
for (i in 1:2000) data.table::set(df, j = as.character(i), value = 1)you should use:=instead?If you find yourself creating a data.table with many columns, you should reconsider your whole approach. The package is much better optimized for many rows than for many columns. Consider carefully if you shouldn't switch to something that creates a more "long-format" data.table.
If you want to stay with your approach, check if
length(DT) < truelength(DT)and increase the truelength withsetalloccolif it isn't. Or, if you know the number of iterations, add the necessary number to the truelength usingsetalloccolbefore the loop.Reacted by Jan Gorecki and Noskario@Noskario Sorry for the late reply. As mentioned by Roland, you can either call
setalloccolupfront and add the nubmer of necessary slots to your data.table which is definetely the recommended approach.If you do not really care about memory (a column slot takes up 8 KB IINM) you can also the default of
options(datatable.alloccol)which is currently set1024- added a commit that references this issue
on May 22, 2026
It appears that set() does not always allocate enough slots. Example:
As indicated in the comment above, switching from "set(x, i, j, value)" to "DT[, c(j) := value]" makes it work. The situation seems similar as to what was reported in #1830.
sessionInfo() is: