JQ 聚合和交叉表

JQ Aggregations and Crosstabs

我有一些数据:

[
  {
    "count": 4,
    "trial_status": "Follow up",
    "date": "2015-06-06"
  },
  {
    "count": 3,
    "trial_status": "Hold",
    "date": "2015-06-06"
  },
  {
    "count": 2,
    "trial_status": "Trial",
    "date": "2015-06-06"
  },
  {
    "count": 1,
    "trial_status": "Trial + Confirm",
    "date": "2015-06-06"
  }....

我想转换成

{"2015-06-06": {"Trial + Confirm": 1, "Follow Up": 4, "Hold": 3, "Trial": 2}}

我的任何方法都没有取得太大进展,因此非常感谢您的帮助。

这应该有效:

group_by(.date) | map({
    key: .[0].date,
    value: map({
        key: .trial_status,
        value: .count
    }) | from_entries
}) | from_entries

关键是使用from_entries建立映射。 这是您可以按名称设置 "properties"/keys 的唯一方法。您只需要生成构成对象的 key/value 对。


Santiago 指出您可以使用特殊语法按名称动态设置属性。这也行。

group_by(.date) | map({
    (.[0].date): map({
        (.trial_status): .count
    }) | add
}) | add

如果您因为地图中的地图而头晕目眩,或者如果您更喜欢直接的方法(在这种情况下至少也恰好是快速和简单的),请考虑像这样使用 reduce reduce .[] as $o ({}; . + {($o.date): (.[$o.date] + {($o.trial_status): $o.count} )})

感谢 jq 的空语义,这可以简化并缩短为: reduce .[] as $o ({}; .[$o.date] += { ($o.trial_status): $o.count } )

这是一个使用reduce, destructuring variable binding and setpath

的解决方案
reduce .[] as {count:$c, trial_status:$s, date:$d} (
  {}
; setpath([$d, $s]; $c)
)

如果此过滤器在 filter.jq 中并且 data.json 包含示例数据,则命令

$ jq -M -f filter.jq data.json

生产

{
  "2015-06-06": {
    "Follow up": 4,
    "Hold": 3,
    "Trial": 2,
    "Trial + Confirm": 1
  }
}