您可以将 adata.table
与适当设置的键一起使用。这将节省内存。
然后你可以将你list
的过滤器传递i
给[.data.table
.period <- seq(from = as.Date("2010/1/1", "%Y/%m/%d"), to = as.Date("2012/1/1",
"%Y/%m/%d"), by = "3 months")
.size <- c("XS", "S", "M", "L", "XL")
.number <- as.character(1:100)
DF <- expand.grid(Period = .period, Size = .size, Number = .number, stringsAsFactors = F)
DF$other <- rnorm(nrow(DF))
library(data.table)
DT <- as.data.table(DF)
DT[, `:=`(Period, as.IDate(.period))]
## Period Size Number other
## 1: 2010-01-01 XS 1 0.17947
## 2: 2010-04-01 XS 1 1.43252
## 3: 2010-07-01 XS 1 -0.97142
## 4: 2010-10-01 XS 1 -0.98021
## 5: 2011-01-01 XS 1 -0.62964
## ---
## 4496: 2011-01-01 XL 100 0.65831
## 4497: 2011-04-01 XL 100 -0.45277
## 4498: 2011-07-01 XL 100 -0.14236
## 4499: 2011-10-01 XL 100 -0.02376
## 4500: 2012-01-01 XL 100 -0.11525
all_filters <- list(Period = as.IDate(as.Date("2010/1/1", format = "%Y/%m/%d")),
Size = "L", Number = c("11", "21", "35", "42", "45", "47", "49", "52", "57"))
setkeyv(DT, names(all_filters))
DT[all_filters]
## Period Size Number other
## 1: 2010-01-01 L 11 1.4122
## 2: 2010-01-01 L 21 -0.4923
## 3: 2010-01-01 L 35 1.1262
## 4: 2010-01-01 L 42 1.3527
## 5: 2010-01-01 L 45 -0.3758
## 6: 2010-01-01 L 47 -0.1847
## 7: 2010-01-01 L 49 -0.8503
## 8: 2010-01-01 L 52 -1.0645
## 9: 2010-01-01 L 57 -0.6092
我能看到的唯一问题是您每次都必须重置密钥以确保引用正确的列。此外,您需要确保过滤器标识符与 data.frame 中的列属于同一类 - 使用character
非factor
列可能更容易
编辑
要在多个列上过滤多个级别,请使用CJ
. CJ 是一个交叉连接,(data.table 等效于 expand.grid,带有键集)
all_filters <- list(Period = as.IDate(as.Date("2010/1/1", format = "%Y/%m/%d")),
Size = c("L",'XL'), Number = c("11", "21", "35", "42", "45", "47", "49", "52", "57"))
cj_filter <- do.call(CJ, all_filters)
# note you could avoid this `do.call` line by
# cj_filter <- CJ(Period = as.IDate(as.Date("2010/1/1", format = "%Y/%m/%d")),
Size = c("L",'XL'), Number = c("11", "21", "35", "42", "45", "47", "49", "52", "57"))
setkeyv(DT, names(cj_filter))
DT[cj_filter]
Period Size Number other
1: 2010-01-01 L 11 0.36289104
2: 2010-01-01 L 21 1.26356767
3: 2010-01-01 L 35 -0.18629723
4: 2010-01-01 L 42 0.92267902
5: 2010-01-01 L 45 1.68796072
6: 2010-01-01 L 47 1.75107447
7: 2010-01-01 L 49 0.24048407
8: 2010-01-01 L 52 0.06675221
9: 2010-01-01 L 57 0.49665392
10: 2010-01-01 XL 11 0.33682495
11: 2010-01-01 XL 21 0.67642271
12: 2010-01-01 XL 35 -0.16412768
13: 2010-01-01 XL 42 0.72863394
14: 2010-01-01 XL 45 -0.55527588
15: 2010-01-01 XL 47 1.30850591
16: 2010-01-01 XL 49 1.08688166
17: 2010-01-01 XL 52 -0.31157250
18: 2010-01-01 XL 57 0.43626422
你也可以做
setkeyv(DT, names(all_filters))
DT[do.call(CJ,all_filters)]