我正在尝试将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年而是多年?
答案 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
尚未实现快速排序,因此我们在密钥中允许使用double
。 integer
和character
上的快速排序非常好,因为这些是使用计数排序完成的。 希望有一天我们能够快速排序(现已实施 - 见下文)。numeric
!
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中的类型为numeric
。 2L
是integer
。虽然data.table
接受numeric
,但仍然更喜欢integer
。
数字的快速基数排序自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()语法。
我认为问题可能是您没有先键入数据。