如何通过data.table中的引用删除行?

我的问题与通过引用赋值与data.table拷贝data.table 。 我想知道是否可以通过引用删除行,类似于

DT[ , someCol := NULL]

我想知道

DT[someRow := NULL, ]

我想这个函数不存在的原因很充分,所以也许你可以指出一个通常的复制方法的好替代方法,如下所示。 特别是,用我最喜欢的例子(data.table),

DT = data.table(x = rep(c("a", "b", "c"), each = 3), y = c(1, 3, 6), v = 1:9)
#      x y v
# [1,] a 1 1
# [2,] a 3 2
# [3,] a 6 3
# [4,] b 1 4
# [5,] b 3 5
# [6,] b 6 6
# [7,] c 1 7
# [8,] c 3 8
# [9,] c 6 9

假设我想从这个data.table中删除第一行。 我知道我可以这样做:

DT <- DT[-1, ]

但是我们经常会想要避免这种情况,因为我们正在复制对象(并且这需要大约3 * N内存,如果这里指出了N object.size(DT) ,现在我发现了set(DT, i, j, value)我知道如何设置特定的值(例如:将行1和2以及列2和3的所有值设置为零)

set(DT, 1:2, 2:3, 0) 
DT
#      x y v
# [1,] a 0 0
# [2,] a 0 0
# [3,] a 6 3
# [4,] b 1 4
# [5,] b 3 5
# [6,] b 6 6
# [7,] c 1 7
# [8,] c 3 8
# [9,] c 6 9

但是我怎么能擦掉前两行? 干

set(DT, 1:2, 1:3, NULL)

将整个DT设置为NULL。

我的SQL知识是非常有限的,所以你们告诉我:由于data.table使用SQL技术,是否有与SQL命令等价的功能

DELETE FROM table_name
WHERE some_column=some_value

在data.table中?


好问题。 data.table无法通过引用删除行。

正如你所知, data.table可以通过引用添加和删除列,因为它会过度分配列指针的向量。 计划是为行做类似的事情,并允许快速insertdelete 。 行删除会使用C中的memmove来删除行后的项目(在每一列中)。 与行存储数据库(例如SQL)相比,在表中间删除行仍然效率不高,这更适合于快速插入和删除表中行的位置。 但是,仍然会比复制没有删除行的新大对象快得多。

另一方面,由于列向量会被过度分配,因此行可以立即插入(并删除) 例如,成长时间序列。


我为了使内存使用类似于就地删除而采取的方法是每次对列进行子集删除。 没有一个适当的C memmove解决方案,但内存使用是我所关心的这里。 像这样的东西:

DT = data.table(col1 = 1:1e6)
cols = paste0('col', 2:100)
for (col in cols){ DT[, (col) := 1:1e6] }
keep.idxs = sample(1e6, 9e5, FALSE) # keep 90% of entries
DT.subset = data.table(col1 = DT[['col1']][keep.idxs]) # this is the subsetted table
for (col in cols){
  DT.subset[, (col) := DT[[col]][keep.idxs]]
  DT[, (col) := NULL] #delete
}

这是一个基于@ vc273的答案和@弗兰克的反馈的工作函数。

delete <- function(DT, del.idxs) {           # pls note 'del.idxs' vs. 'keep.idxs'
  keep.idxs <- setdiff(DT[, .I], del.idxs);  # select row indexes to keep
  cols = names(DT);
  DT.subset <- data.table(DT[[1]][keep.idxs]); # this is the subsetted table
  setnames(DT.subset, cols[1]);
  for (col in cols[2:length(cols)]) {
    DT.subset[, (col) := DT[[col]][keep.idxs]];
    DT[, (col) := NULL];  # delete
  }
   return(DT.subset);
}

其用法示例如下:

dat <- delete(dat,del.idxs)   ## Pls note 'del.idxs' instead of 'keep.idxs'

其中“dat”是一个data.table。 从我的笔记本电脑上移除1.4M行的14K行需要0.25秒。

> dim(dat)
[1] 1419393      25
> system.time(dat <- delete(dat,del.idxs))
   user  system elapsed 
   0.23    0.02    0.25 
> dim(dat)
[1] 1404715      25
> 

PS。 由于我是新手,因此无法向@ vc273的主题添加评论:-(

链接地址: http://www.djcxy.com/p/68789.html

上一篇: How to delete a row by reference in data.table?

下一篇: Best Practices for cache locality in Multicore Parallelism in F#