I’ve been struggling for the last 2 days with this and I really need your help. I’m trying to convert a table into an array. In the end I wanna be able to compare values of different array indexes.
This query gives me some results but I’m not quite there yet…
Basically what I’m looking for ‘difference’ function but instead of calculating ‘subsequent’ columns, I want to calculate difference between rowN._value and rowM._value where N and M is the row number. Something like below, but below code wont work since map() function syntax is different.
data = from(bucket: "test-bucket")
|> range(start: timeRangeStart, stop: timeRangeStop)
|> filter(fn: (r) => r._measurement == "usdMarket" and r._field == "close" and r.symbol == "ETH")
arr_data = data
|> findColumn(fn: (key) => true, column: "_value")
data
|> limit(n:1, offset: 0)
|> map(fn: (r) => ({
m = n + 2
r with differenceValue: arr_data[n] - arr_data[m]
n = n + 1
}),
identity: {n: 0})
@gorkem You were really close with this query. In this specific case, I’d suggest creating a custom function that lets you specify the row numbers to use in the operation and then map over input tables (just placeholder data is necessary here) using those custom parameters. Something like this:
we need to have dynamic variables in rowDiff function. so it should be similar to this;
rowDiff = (x, n) => array.from(rows: [{placeholder: 0}])
|> map(fn: (r) => ({
differenceValue: arr_data[n] - arr_data[n+x]
n: n + 1
}))
rowDiff(x:2, n:0)
// where x is the number of steps between rows that we want to calculate the difference.
// for example built-in function difference() in influx calculate subsequent rows, in other words x is 1 in this function.
// n is the starting index. this should be inceremented by 1 in each iteration. But I dont know if this is a thing.
// I know in reduce function, it is possible to increment accumulator.count variable but I'm not sure if something like this is possible in map() function
Gotcha. So Flux doesn’t provide row indexes, but you can manually hack/add them. In order to successfully return value differences for rows who’s calculation would reference non-existent indexes, you have to convert the values to floats to get access to the NaN float value.
I’ve tested this against the data in your screenshot and it works:
data = from(bucket: "test-bucket")
|> range(start: timeRangeStart, stop: timeRangeStop)
|> filter(fn: (r) => r._measurement == "usdMarket" and r._field == "close" and r.symbol == "ETH")
rowDiff = (x, tables=<-) => {
_arr_data = tables |> findColumn(fn: (key) => true, column: "_value")
_max_index = length(arr: _arr_data) - 1
_indexed_rows = tables
|> map(fn: (r) => ({ r with index: 1 }))
|> cumulativeSum(columns: ["index"])
|> map(fn: (r) => ({ r with index: r.index - 1 }))
_output = _indexed_rows
|> map(fn: (r) => ({ r with differenceValue:
if (r.index + x) > _max_index or (r.index + x) < 0 then
float(v: "NaN")
else
float(v: _arr_data[r.index]) - float(v: _arr_data[r.index + x])
}))
return _output
}
data
|> rowDiff(x: 2)