data.table中的子集

exl*_*exl 17 r subset data.table

我试图在R(而不是data.frame)中对data.table(来自包data.table)进行子集化.我有一个4位数的年份作为关键.我想通过一系列的几年来分组.例如,我想要提取1999年,2000年,2001年的所有记录.

我试过传递DT[J(year)]以下二进制搜索语法:

1999,2000,2001
c(1999,2000,2001)
1999, 2000, 2001
Run Code Online (Sandbox Code Playgroud)

但这些似乎都不起作用.任何人都知道如何做一个子集,你想要选择的年份不只是1年,而是多年?

Ric*_*ton 19

什么适用于data.frames适用于data.tables.

subset(DT, year %in% 1999:2001)
Run Code Online (Sandbox Code Playgroud)

  • 不是一切:`dt < - data.table(a = c(1,2,3),b = c(4,5,6),c = c(7,8,9)); dt [,c('b','c')]`返回列名称的向量 - 使用data.frame,它返回列. (6认同)
  • `data.table` 现在有自己的 `subset`: `subset.data.table {data.table}` (2认同)

Art*_*hur 15

问题不明确,并没有提供足够的数据来处理它但它是有用的,所以如果有人可以用我以后提供的数据编辑它,那么欢迎一个.这篇文章的标题也可以完成:Matthew Dowle经常回答两个向量子集的问题,但不太常见的是按照一个向量的一个对象的子集化.我一直在寻找一个答案,直到这里找到一个字符向量.

让我们考虑一下这些数据:

library(data.table)
n <- 100
X <- data.table(a=sample(c(10,20,25,30,40),n,replace=TRUE),b=1:n)
Run Code Online (Sandbox Code Playgroud)

对应的data.table样式查询在X[X$a %in% c(10,20),]某种程度上令人惊讶:

setkey(X,a)
X[.(c(10,20))]
X[.(10,20)] # works for characters but not for integers
            # instead, treats 10 as the filter
            # and 20 as a new variable

# for comparison :
X[X$a %in% c(10,20),]
Run Code Online (Sandbox Code Playgroud)

现在,哪个最好?如果您的密钥已经设置,data.table,显然.否则,它可能不会,因为证明以下时间测量(在我的1,75 Go RAM计算机上):

n <- 1e7
X <- data.table(a=sample(c(10,20,25,30,40),n,replace=TRUE),b=1:n)
system.time(X[X$a %in% c(10,20),])
# utilisateur     système      écoulé (yes, I'm French) 
#        1.92        0.06        1.99
system.time(setkey(X,a))
# utilisateur     système      écoulé 
#       34.91        0.05       35.23 
system.time(X[J(c(10,20))])
# utilisateur     système      écoulé 
#        0.15        0.08        0.23
Run Code Online (Sandbox Code Playgroud)

但也许马修有更好的解决方案......


[马修]你发现排序类型numeric(又名double)要慢得多integer.多年来,我们没有允许double用户因担心用户陷入此陷阱并报告这样糟糕的时间.double由于尚未实现快速排序,我们允许在键中进行一些惶恐double.快速排序integer并且character非常好,因为这些是使用计数排序完成的.希望numeric有一天我们能快速排序!(现已实施 - 见下文).

关于data.table的时间安排在1.9.0之前

n <- 1e7
X <- data.table(a=sample(c(10,20,25,30,40),n,replace=TRUE),b=1:n)      
system.time(setkey(X,a))
#   user  system elapsed 
# 13.898   0.138  14.216 

X <- data.table(a=sample(as.integer(c(10,20,25,30,40)),n,replace=TRUE),b=1:n)
system.time(setkey(X,a))
#   user  system elapsed 
#  0.381   0.019   0.408 
Run Code Online (Sandbox Code Playgroud)

默认情况下在R中2键入的记忆numeric.2Linteger.虽然data.table接受numeric它仍然更喜欢integer.


从v1.9.0开始实现数字的快速基数排序.

从v1.9.0开始

n <- 1e7
X <- data.table(a=sample(c(10,20,25,30,40),n,replace=TRUE),b=1:n)      
system.time(setkey(X,a))
#    user  system elapsed 
#   0.832   0.026   0.871 
Run Code Online (Sandbox Code Playgroud)


Yik*_* Lu 8

像上面一样,但更多data.table esque:

DT[year %in% c(1999, 2000, 2001)]

  • 没错,但我们不想鼓励矢量扫描.问题非常糟糕.如果他们包含了基本示例和错误消息,则可以使用二进制搜索来解决. (3认同)