Flo*_*ald 144 r data.table
我的问题与引用分配和复制分配有关data.table.我想知道是否可以通过引用删除行,类似于
DT[ , someCol := NULL]
Run Code Online (Sandbox Code Playgroud)
我想知道
DT[someRow := NULL, ]
Run Code Online (Sandbox Code Playgroud)
我想有一个很好的理由说明为什么这个功能不存在,所以也许你可以指出一个很好的替代通常的复制方法,如下所示.特别是,从我的例子(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
Run Code Online (Sandbox Code Playgroud)
假设我想从此data.table中删除第一行.我知道我可以这样做:
DT <- DT[-1, ]
Run Code Online (Sandbox Code Playgroud)
但通常我们可能想要避免这种情况,因为我们正在复制对象(这需要大约3*N内存,如果是N object.size(DT),如此处所指出的那样.现在我发现set(DT, i, j, value).我知道如何设置特定值(如下所示:set all第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
Run Code Online (Sandbox Code Playgroud)
但是,如何删除前两行呢?干
set(DT, 1:2, 1:3, NULL)
Run Code Online (Sandbox Code Playgroud)
将整个DT设置为NULL.
我的SQL知识非常有限,所以你们告诉我:给定的data.table使用SQL技术,是否有与SQL命令相同的功能
DELETE FROM table_name
WHERE some_column=some_value
Run Code Online (Sandbox Code Playgroud)
在data.table?
Mat*_*wle 119
好问题.data.table无法通过引用删除行.
data.table可以通过引用添加和删除列,因为它会过度分配列指针的向量,如您所知.计划是为行做类似的事情,并允许快速insert和delete.行删除将memmove在C中用于在删除的行之后预订项目(在每一列中).与诸如SQL之类的行存储数据库相比,删除表中间的行仍然是非常低效的,这更适合于快速插入和删除表中这些行的任何位置.但是,它仍然比复制没有删除行的新大对象快得多.
另一方面,由于列向量将被过度分配,因此可以在末尾立即插入(和删除)行; 例如,不断增长的时间序列.
它是一个问题:通过引用删除行.
vc2*_*273 28
我为使内存使用而采取的方法类似于就地删除是一次对列进行子集并删除.没有正确的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
}
Run Code Online (Sandbox Code Playgroud)
这是一个基于@ vc273的答案和@Frank的反馈的工作函数.
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);
}
Run Code Online (Sandbox Code Playgroud)
其用法示例:
dat <- delete(dat,del.idxs) ## Pls note 'del.idxs' instead of 'keep.idxs'
Run Code Online (Sandbox Code Playgroud)
其中"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
>
Run Code Online (Sandbox Code Playgroud)
PS.由于我是SO的新手,我无法在@ vc273的帖子中添加评论:-(
这个话题仍然让很多人(包括我)感兴趣。
那个怎么样?我曾经assign替换过glovalenv和 前面描述的代码。捕获原始环境会更好,但至少globalenv它具有内存效率,并且就像通过引用进行更改一样。
delete <- function(DT, del.idxs)
{
varname = deparse(substitute(DT))
keep.idxs <- setdiff(DT[, .I], del.idxs)
cols = names(DT);
DT.subset <- data.table(DT[[1]][keep.idxs])
setnames(DT.subset, cols[1])
for (col in cols[2:length(cols)])
{
DT.subset[, (col) := DT[[col]][keep.idxs]]
DT[, (col) := NULL]; # delete
}
assign(varname, DT.subset, envir = globalenv())
return(invisible())
}
DT = data.table(x = rep(c("a", "b", "c"), each = 3), y = c(1, 3, 6), v = 1:9)
delete(DT, 3)
Run Code Online (Sandbox Code Playgroud)
相反,或者尝试设置为 NULL,请尝试设置为 NA(匹配第一列的 NA 类型)
set(DT,1:2, 1:3 ,NA_character_)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
45448 次 |
| 最近记录: |