Incanter - 如何使用带有列关键字的过滤器而不是nth?

时间:2014-01-06 11:28:36

标签: clojure incanter

(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是否有办法执行此筛选查询,仍然允许我使用列关键字?例如,我可以让这个工作,因为我知道:卷是第5列

(icore/sel data :filter #(> (nth % 5) 1000000))

但是,我想再看看Incanter是否有办法为这种类型的过滤查询保留列关键字。

1 个答案:

答案 0 :(得分:3)

示例数据集:

(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的=之外,还有几个此类“谓词关键字”支持}),:nenot=),:in:nin(不在)。

:fn是一般的“使用任何函数”关键字。

所有这些都可以加上$:$fn等)作为前缀,但意义不变。