You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Submitted by: Matt Dowle; Assigned to: Nobody; R-Forge link
Since deleting 1 column is DT[,colname:=NULL], and deleting rows is the same as deleting all columns for those rows, and we wish to use hierarchical indexes to find the rows to delete by reference, we just need a LHS to indicate "all" columns, leading to :
DT[i,.:=NULL] # delete rows by reference
DT[,.:=NULL] # error("must specify i to delete rows. To delete all rows from a table use DT[TRUE,.:=NULL], or, DT=DT[0]. This is deliberately a little harder, to avoid accidents such as "delete from table" a coomon accident in SQL.")
We can also add an attribute "read only" or "protect" to a data.table, and if the user had protected the data.table in that way, .:= would not work on it.
if anyone needs a quick-and-dirty solution, as I did, here is a memory-efficient function to select rows for each col then delete by reference based on a SO answer by vc273.
Reacted by Christophe Dervieux, Andrew J. Rech, Juha L, Boudewijn Aasman, micstr, David Andel, Hans Ekbrand, Ciaran Gilbert, Kipp Johnson, Matthew Son and 2 more
Reacted by Juanjo, Andrew J. Rech and Tokhir Dadaev
In case of updates, you will see comments here, or in exists, in a linked PR.
BTW. I have impression that many readers misunderstood benefits of this function. It will most likely be slower than copy as it has to be made now. It will not have to allocate memory for extra copy of data.table, but that allocated memory is released just after assignment, so it is really relevant only when you run into OOM error, that could be avoidable if your data would be twice smaller.
Reacted by Michael Chirico, Jan Gleixner, steffiOnCode and Brock
@ben-schwen has the recent update to move growable vectors inside the API for R changed what's possible here (for better or worse)?
Neither, I would say. The new resizable vectors API now allows allocating larger vectors and resizing them in-place, smth we have down since a long time "ab"using TRUELENGTH.
To implement this feature cleanly we would need to maintain a row index either as
attribute (volatile since we now that a lot of attributes get swiped)
If we want only to delete rows and not add by reference then maintaining index is not needed. We just shrink each column after moving its data to front.
Activity
Co0olCat commentedon May 7, 2015
zx8754 commentedon Oct 1, 2015
Subset data table without using <-
mattdowle commentedon Oct 1, 2015
http://stackoverflow.com/questions/10790204/how-to-delete-a-row-by-reference-in-r-data-table
mattdowle commentedon Oct 1, 2015
Just delete by reference is not that hard. The benefit would be mainly memory efficiency rather than speed so much.
mattdowle commentedon Oct 29, 2015
How about adding both
delete(DT, b>=8 | a<=3)and
DT[b>=8 | a<=8, .ROW:=NULL]The advantage of the latter would be combining with other features of
[]such as row numbers ini, join iniandroll. All benefiting from[i,j,by]optimization.As per : http://stackoverflow.com/questions/10790204/how-to-delete-a-row-by-reference-in-r-data-table/10791729?noredirect=1#comment54633906_10791729
mattdowle commentedon Oct 29, 2015
More advanced example :
Is
.ROWthe right name for this new symbol?[-][R-Forge #2092] Delete rows by reference[/-][+]Delete rows by reference[/+]eantonya commentedon Oct 29, 2015
Re right name: doesn't
.SDalready carry the right meaning for that (instead of introducing a new name a la.ROW)?franknarf1 commentedon Oct 29, 2015
I think syntax for selecting rows to keep (which just deletes their complement) would be convenient.
I don't know that there's a sensible way to extend this logic to work inside
j. I'd just as well have Matt's second example only work viaJust as new columns cannot be created by
set(last I checked), it could be that row modifications cannot be done inside[.data.table.andrewrech commentedon Aug 23, 2016
if anyone needs a quick-and-dirty solution, as I did, here is a memory-efficient function to select rows for each col then delete by reference based on a SO answer by vc273.
vinhdizzo commentedon Aug 25, 2016
@andrewrech I can't get your code to work. I'm on the dev version of data.table, and when I run your code, I end up with an empty data.table:
jarppiko commentedon Nov 18, 2016
To complement @andrewrech's answer. Here is code as function and example of its usage.
And example of its usage:
dat <- delete(dat, del.idxs)Where "dat" is a data.table. Removing 14k rows from 1.4M rows takes 0.25 sec on my laptop.
This is my very first GitHub post, btw.
juanpide commentedon Jan 9, 2017
vikram-rawat commentedon Aug 16, 2017
MiloParigi commentedon Jan 3, 2018
What kind of work needs to be done in order to add this functionality to data.table ? Would be glad to help, but not totally sure where to start !
The delete function could be added using @jarno-p awnser and later on modified to be more efficient and works with
[]references, don't you think ?7 remaining items
jangorecki commentedon Apr 7, 2020
Proof of concept based on #4345 (comment)
jangorecki commentedon Nov 17, 2022
working example using
setsubsetbranchfranknarf1 commentedon Nov 17, 2022
Cool!
I'm wondering if the
setloop can be avoided along these lines:Or if
setorderisn't reliably order-preserving (the documentation doesn't advertise it):It looks like memory addresses survive these operations (?).
If the current approach is necessary, I think you could swap...
for something like
Why? Speed (avoiding setdiff and scaling with nrow(x)) and handling the edge case where all rows are kept
jangorecki commentedon Nov 17, 2022
Wonderful idea!
Would you like to take over the branch?
Ultimately we want this functionality to be inside [ rather than just new function...
michaelsimmler commentedon Oct 23, 2023
waynelapierre commentedon Nov 16, 2023
jangorecki commentedon Nov 16, 2023
In case of updates, you will see comments here, or in exists, in a linked PR.
BTW. I have impression that many readers misunderstood benefits of this function. It will most likely be slower than copy as it has to be made now. It will not have to allocate memory for extra copy of data.table, but that allocated memory is released just after assignment, so it is really relevant only when you run into OOM error, that could be avoidable if your data would be twice smaller.
MichaelChirico commentedon Dec 26, 2025
@ben-schwen has the recent update to move growable vectors inside the API for R changed what's possible here (for better or worse)?
ben-schwen commentedon Dec 26, 2025
Neither, I would say. The new resizable vectors API now allows allocating larger vectors and resizing them in-place, smth we have down since a long time "ab"using
TRUELENGTH.To implement this feature cleanly we would need to maintain a row index either as
where I currently would favor 2) or 3).
jangorecki commentedon Dec 27, 2025
If we want only to delete rows and not add by reference then maintaining index is not needed. We just shrink each column after moving its data to front.
ben-schwen commentedon Dec 27, 2025
I just wrote a POC in C for this. As pointed out by Matt, speed will be the same. Used memory will be roughly half.
Benchmarking with
cgmemtimeshows exactly the same ratio of saving half the memory (as expected).