17

我正在尝试在 R(不是data.frame)中对 data.table (来自包data.table )进行子集化。我有一个 4 位数的年份作为密钥。我想通过一系列年份来细分。例如,我想提取 1999、2000、2001 年的所有记录。

我尝试在我的DT[J(year)]二进制搜索语法中传递以下内容:

1999,2000,2001
c(1999,2000,2001)
1999, 2000, 2001

但这些似乎都不起作用。任何人都知道如何做一个子集,其中您要选择的年份不仅仅是 1 年,而是多年?

4

4 回答 4

19

data.frames 有效的对data.tables 有效。

subset(DT, year %in% 1999:2001)
于 2011-03-30T16:41:48.917 回答
16

这个问题不清楚,也没有提供足够的数据来处理,但它很有用,所以如果有人可以用我以后提供的数据编辑它,欢迎提供。帖子的标题也可以完成:Matthew Dowle 经常回答 subsetting-over-two-vectors 问题,但较少回答 subsetting-according-a-in-statement-on-one-vector 的问题。我一直在寻找答案,直到在这里找到一个字符向量。

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

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

对应的 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),]

现在,哪个最好?如果您的密钥已经设置,显然是 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

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


[Matthew] 您发现排序类型numeric(又名double)比integer. 多年来,我们不允许double输入密钥,因为担心用户会落入这个陷阱并报告这样的糟糕时机。我们有些担心地允许double输入键,因为目前还没有实现快速排序double。快速排序integer并且character非常好,因为这些是使用计数排序完成的。希望有一天我们能快速分类!numeric(现已实施 - 见下文)。

1.9.0 之前的 data.table 上的计时

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 

请记住,默认情况下2输入numericR。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 
于 2013-03-08T16:15:00.127 回答
8

与上面类似,但更多 data.table esque:

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

于 2012-05-26T16:50:37.723 回答
1

这将起作用:

sample_DT = data.table(year = rep(1990:2010, length.out = 1000), 
                       random_number = rnorm(1000), key = "year")
year_subset = sample_DT[J(c(1990, 1995, 1997))]

类似地,您可以使用 setkey(existing_DT, year) 键入已经存在的 data.table,然后使用 J() 语法,如上所示。

我认为问题可能在于您没有先键入数据。

于 2014-05-05T21:25:55.087 回答