(require '[incanter.core :as icore])
;; Assume dataset "data" is already loaded by incanter.core/read-dataset
;; Let's examine the columns (note that Volume is the 5th column)
(icore/col-names data)
==> [:Date :Open :High :Low :Close :Volume]
;; We CAN use the :Volume keyword to look at just that column
(icore/sel data :cols Volume)
==> (11886469 9367474 12847099 9938230 11446219 12298336 15985045...)
;; But we CANNOT use the :Volume keyword with filters
;; (well, not without looking up the position in col-names first...)
(icore/sel data :filter #(> (#{:Volume} %) 1000000))
显然,这是因为过滤器的 anon 函数正在查看 LazySeq,它不再将列名作为其结构的一部分,因此上面的代码甚至不会编译。我的问题是:Incanter 是否有办法执行此过滤查询,仍然允许我使用列关键字?例如,我可以让它工作,因为我知道:Volume 是第 5 列
(icore/sel data :filter #(> (nth % 5) 1000000))
不过,我再次查看 Incanter 是否有办法为这种类型的过滤查询保留列关键字。
示例数据集:
(def data
(icore/dataset
[:foo :bar :baz :quux]
[[0 0 0 0]
[1 1 1 1]
[2 2 2 2]]))
包含结果的示例查询:
(icore/$where {:baz {:fn #(> % 1)}} data)
| :foo | :bar | :baz | :quux |
|------+------+------+-------|
| 2 | 2 | 2 | 2 |
其实这也可以写
(icore/$where {:baz {:gt 1}} data)
除了:gt
之外,还有几个这样的"谓词关键字"是支持的::lt
、:lte
、:gte
、:eq
(对应于Clojure的=
)、:ne
(not=
)、:in
、:nin
(不在)。
:fn
是通用的"使用任何功能"关键字。
所有这些都可以以$
(:$fn
等)为前缀,含义没有变化。