data.table中的子集

时间:2011-03-30 13:52:57

标签: r subset data.table

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

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

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

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

4 个答案:

答案 0 :(得分:19)

适用于data.frame的{​​{1}}适用于data.table

subset(DT, year %in% 1999:2001)

答案 1 :(得分:15)

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

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

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

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

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(a.k.a。double)比integer慢得多。多年来,由于担心用户陷入此陷阱并报告这样糟糕的时间,我们不允许double进入密钥。由于double尚未实现快速排序,因此我们在密钥中允许使用doubleintegercharacter上的快速排序非常好,因为这些是使用计数排序完成的。 希望有一天我们能够快速排序numeric(现已实施 - 见下文)。

在1.9.2之前的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在R中的类型为numeric2Linteger。虽然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 

答案 2 :(得分:8)

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

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

答案 3 :(得分: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()语法。

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