How to add an additional field to the dataset in Vega-Lite - vega-lite

I am working on preparing a vega chart and my dataset is as follows:
data: {
"values": [
{"key": "title1", "value": "100"},
{"key": "title2", "value": "500"},
{"key": "title3", "value": "400"},
{"key": "title4", "value": "200"},
{"key": "title5", "value": "600"},
{"key": "title6", "value": "50"},
{"key": "title7", "value": "10"}
]}
I want to add another field 'result' to this array whose value is based on the existing value field.
For example:
result['title1'] = value['title1'] / value['title2']
result['title2'] = value['title2'] / value['title3']
Output:
data: {
"values": [
{"key": "title1", "value": "100", "result": 0.2},
{"key": "title2", "value": "500", "result": 1.25},
...
]}
I tried using transform in vega-lite but was not able to achieve it.
How can I achieve it?

Use a window transform as per comments.

Related

How to project column name and value from JSON in KQL?

I have the following 'SetOfSignals' in KQL (using mv-expand):
"SetOfSignals": {
"name": "CompanyName",
"signals": [
{
"name": "AmbientAirTemperature",
"unit": "C",
"dataType": "Float32",
"values": [
"11.5"
]
},
{
"name": "AverageEnergyConsumption",
"unit": "W",
"dataType": "Float32",
"values": [
"780.0"
]
}
}
and now I want to project the signal names with corresponding values.
I want it to look like this:
...
AmbientAirTemperature
AverageEnergyConsumption
...
11.5
780.0
but using something like | extend AmbientAirTemperature = signals.name doesn't works since there are multiple strings within "signals" with the name "name".
Thanks.
datatable(SetOfSignals:dynamic)
[
dynamic
(
{
"name": "CompanyName",
"signals": [
{
"name": "AmbientAirTemperature",
"unit": "C",
"dataType": "Float32",
"values": [
"11.5"
]
},
{
"name": "AverageEnergyConsumption",
"unit": "W",
"dataType": "Float32",
"values": [
"780.0"
]
}
]
}
)
]
| mv-apply signal = SetOfSignals.signals on
(
summarize make_bag(bag_pack(tostring(signal.name), signal.values[0]))
)
| project-away SetOfSignals
| evaluate bag_unpack(bag_)
AmbientAirTemperature
AverageEnergyConsumption
11.5
780.0
Fiddle

VegaLite Split Slices and aggregate by ranges

I'm trying to create a similar dashboard using VegaLite:
My example is in this link
Is there a way to configure the ranges in the dashboard and show it in a similar way as in the screenshot?
In need to devide the pie chart to two ranges:
0<=x<1
X>=1
You could use a binned transform or if you want just two discrete categories then a calculated field works just fine and can also be used in the legend.
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"description": "A simple pie chart with embedded data.",
"data": {
"values": [
{"username": "client1", "value": 4},
{"username": "client2", "value": 0.6},
{"username": "client3", "value": 0},
{"username": "client4", "value": 3},
{"username": "client5", "value": 7},
{"username": "client6", "value": 8}
]
},
"transform": [
{"calculate": "datum.value>=3?'>=3':'<3'" ,"as": "binned"}
]
,
"mark": "arc",
"encoding": {
"theta": {"field": "value", "type": "quantitative", "aggregate": "count" },
"color": {"field": "binned", "type": "nominal"}
}
}

Top level JSON object with multiple matches returned for each match

I have this kind of JSON file:
[{
"name": "model1",
"reference": 0.1,
"code": [{
"name": "foo",
"version": "a",
"value": 0.2
},{
"name": "foo",
"version": "b",
"value": 0.2
},{
"name": "bar",
"version": "a",
"value": 0.15
}]
},{
"name": "model2",
"reference": 0.12,
"code": [{
"name": "bar",
"version": "a",
"value": 0.09
},{
"name": "baz",
"version": "a",
"value": 0.15
}]
}]
What I want is to get all the top level objects for a certain code.name, let’s say foo. So I wrote the following query:
.[] | select( .code[].name == "foo" )
The problem is that since there is two sub-objects with foo as name, the top level object is returned twice. I’d like to have it only once, is that possible?
You're looking for any/1.
.[] | select(.code | any(.name == "foo"))
Online demo

Format nested JSON input using JQ?

I am trying to convert the sample input below into the output below using jq:
Input JSON
"elements": [
{
"type": "CustomObjectData",
"id": "2185",
"fieldValues": [
{
"type": "FieldValue",
"id": "169",
"value": "9/6/2017 12:00:00 AM"
},
{
"type": "FieldValue",
"id": "190",
"value": "ABC"
}
]
},
{
"type": "CustomObjectData",
"id": "2186",
"contactId": "13",
"fieldValues": [
{
"type": "FieldValue",
"id": "169",
"value": "8/31/2017 12:00:00 AM"
},
{
"type": "FieldValue",
"id": "190",
"value": "DEF"
}
]
}
]
Desired Output (group by id)
Essentially trying to extract "value" field from each "fieldValues" object and group them by "id"
{
"id:"2185",
"value": "9/6/2017 12:00:00 AM",
"value": "ABC"
},
{
"id:"2186",
"value": "8/31/2017 12:00:00 AM",
"value": "DEF"
}
What jq syntax should i use to achieve this? Thanks very much!!
Assuming the input shown in the Q has been modified in the obvious way to make it valid JSON, the following filter will produce the output as shown below, that is, a stream of valid JSON values that is similar to the allegedly expected output included in the Q. If a single array is desired, one possibility would be to wrap the program in square brackets.
program.jq
.elements[]
| {id, values: [ .fieldValues[].value] }
Output
{
"id": "2185",
"values": [
"9/6/2017 12:00:00 AM",
"ABC"
]
}
{
"id": "2186",
"values": [
"8/31/2017 12:00:00 AM",
"DEF"
]
}
Producing CSV
One of many possibilities:
.elements[]
| [.id] + [.fieldValues[].value]
| #csv
With the -r command-line option, this produces the following CSV:
"2185","9/6/2017 12:00:00 AM","ABC"
"2186","8/31/2017 12:00:00 AM","DEF"

Using jq to convert object to key with values

I have been playing around with jq to format a json file but I am having some issues trying to solve a particular transformation. Given a test.json file in this format:
[
{
"name": "A", // This would be the first key
"number": 1,
"type": "apple",
"city": "NYC" // This would be the second key
},
{
"name": "A",
"number": "5",
"type": "apple",
"city": "LA"
},
{
"name": "A",
"number": 2,
"type": "apple",
"city": "NYC"
},
{
"name": "B",
"number": 3,
"type": "apple",
"city": "NYC"
}
]
I was wondering, how can I format it this way using jq?
[
{
"key": "A",
"values": [
{
"key": "NYC",
"values": [
{
"number": 1,
"type": "a"
},
{
"number": 2,
"type": "b"
}
]
},
{
"key": "LA",
"values": [
{
"number": 5,
"type": "b"
}
]
}
]
},
{
"key": "B",
"values": [
{
"key": "NYC",
"values": [
{
"number": 3,
"type": "apple"
}
]
}
]
}
]
I have followed this thread Using jq, convert array of name/value pairs to object with named keys and tried to group the json using this expression
jq '. | group_by(.name) | group_by(.city) ' ./test.json
but I have not been able to add the keys in the output.
You'll want to group the items at the different levels and building out your result objects as you want.
group_by(.name) | map({
key: .[0].name,
values: (group_by(.city) | map({
key: .[0].city,
values: map({number,type})
}))
})
Just keep in mind that group_by/1 yields groups in a sorted order. You'll probably want an implementation that preserves that order.
def group_by_unsorted(key_selector):
reduce .[] as $i ({};
.["\($i|key_selector)"] += [$i]
)|[.[]];