gtsummary - providing mean of means - gtsummary

library(gtsummary)
table1_test <- test %>%
select(period, hr_avg_relative, hr_max_relative )%>%
tbl_summary(by = period, statistic = list(
all_continuous() ~ "{mean} ± {sd} ",
all_categorical() ~ "{n} / {N} ({p}%)"))%>%
bold_labels() %>%
modify_header(label = "**Variable**" )
The previous working code provides a summary of ALL observations.
However, each id provides multiple observations. Instead of provinding a mean of all observations, can gtsummary provide the mean of each id's means?
df below
test <- structure(list(period = c("pre", "pre", "pre", "post", "post",
"post", "post", "post", "post", "pre", "pre", "pre", "pre", "pre",
"pre", "post", "post", "post", "pre", "pre", "pre", "post", "post",
"post"), id = c(1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 2, 2, 2,
2, 2, 2, 4, 4, 4, 4, 4, 4), hr_max_relative = c(0.866279069767442,
0.877906976744186, 0.802325581395349, 0.866279069767442, 0.918604651162791,
0.872093023255814, 0.879120879120879, 0.857142857142857, 0.857142857142857,
0.857142857142857, 0.89010989010989, 0.89010989010989, 0.941798941798942,
0.873015873015873, 0.899470899470899, 0.899470899470899, 0.915343915343915,
0.878306878306878, 0.844919786096257, 0.844919786096257, 0.855614973262032,
0.903743315508021, 0.914438502673797, 0.866310160427808), hr_avg_relative = c(0.796511627906977,
0.808139534883721, 0.761627906976744, 0.808139534883721, 0.837209302325581,
0.813953488372093, 0.763736263736264, 0.796703296703297, 0.785714285714286,
0.763736263736264, 0.802197802197802, 0.785714285714286, 0.878306878306878,
0.793650793650794, 0.835978835978836, 0.835978835978836, 0.804232804232804,
0.80952380952381, 0.689839572192513, 0.72192513368984, 0.754010695187166,
0.754010695187166, 0.796791443850267, 0.786096256684492)), row.names = c(NA,
-24L), class = c("tbl_df", "tbl", "data.frame"))

Related

how to read value from Json flutter

hello i have an object Json which have some values as payload , key , card .. so i aim to get the data i need directly with key "payload" .
var dataFinal= tag.data.toString();
and this what i get if i print my data
[log] handle {nfca: {identifier: [12, 4, 18, 17], atqa: [4, 0], maxTransceiveLength: 253, sak: 8, timeout: 618}, mifareclassic: {identifier: [99, 4, 150, 17], blockCount: 64, maxTransceiveLength: 253, sectorCount: 16, size: 1024, timeout: 618, type: 0}, ndef: {identifier: [99, 4, 150, 17], isWritable: true, maxSize: 716, canMakeReadOnly: false, cachedMessage: {records: [{typeNameFormat: 1, type: [84], identifier: [], payload: [1,45,989]}]}, type: com.nxp.ndef.mifareclassic}}
how can i get the payload value ?
You can check out the function jsonDecode() which expects a string as a param and returns dynamic or Map in your case
import 'dart:convert';
Map<String,dynamic> data = jsonDecode(tag.data.toString());
print(data["nfca"]);

pg-promise update multiple not setting columns correctly

I have a project where I need to do a update multiple rows at once. I have found the example on how to do this is the docs: documentation
I have done used a columnset because it is being recommended to do to in the documentations. I have set the ?feature_id so it is only used in the WHERE clause.
The error my code is generating is the following: error: column "created_on" is of type timestamp with time zone but expression is of type text. I have noticed in the query that is being generated and that seems to be in line with the example.
This code has an insert statement for the features that are new and that seems to work fine. The error is only being thrown on the update query.
const insertValues = [];
const updateValues = [];
for (let i = 0; i < features.length; i += 1) {
const feature = features[i];
if (!excistingFeaturesIds.includes(feature.id)) {
insertValues.push({
plot_id: plotId,
type: feature.type,
area: feature.area,
created_on: currendDate,
updated_on: currendDate,
geo_feature: feature.geoFeature,
});
} else {
updateValues.push({
feature_id: feature.id,
plot_id: plotId,
type: feature.type,
area: feature.area,
created_on: currendDate,
updated_on: currendDate,
geo_feature: feature.geoFeature,
});
}
}
const insertColumnSet = new pgp.helpers.ColumnSet(['plot_id', 'type', 'area', 'created_on', 'updated_on', 'geo_feature'], { table: 'features' });
const updateColumnSet = new pgp.helpers.ColumnSet(['?feature_id', 'plot_id', 'type', 'area', 'created_on', 'updated_on', 'geo_feature'], { table: 'features' });
if (insertValues && insertValues.length > 0) {
const insertQuery = pgp.helpers.insert(
insertValues, insertColumnSet,
);
await promiseDB.none(insertQuery);
}
if (updateValues && updateValues.length > 0) {
const updateQuery = `${pgp.helpers.update(
updateValues, updateColumnSet,
)} WHERE v.feature_id = t.feature_id`;
console.log(updateQuery);
await promiseDB.none(updateQuery);
}
return res.status(201).json({
message: 'Features added!',
});
} catch (err) {
console.log(err);
return res.status(400).send(err);
}
UPDATE
"features" AS t
SET
"plot_id" = v. "plot_id",
"type" = v. "type",
"area" = v. "area",
"created_on" = v. "created_on",
"updated_on" = v. "updated_on",
"geo_feature" = v. "geo_feature"
FROM (
values(1, 3, 'roof', 342.01520314642977, '2021-07-20T09:56:10.007+02:00', '2021-07-20T09:56:10.007+02:00', '{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[coords...]]]},"properties":{"UIDN":6338864,"OIDN":5290477,"VERSIE":1,"BEGINDATUM":"2015-09-23","VERSDATUM":"2015-09-23","TYPE":1,"LBLTYPE":"hoofdgebouw","OPNDATUM":"2015-08-25","BGNINV":5,"LBLBGNINV":"kadastralisatie","type":"roof","tools":"polygon","description":"D1","id":5290477,"area":342.01520314642977,"roofType":"saddle","roofGreen":"normal","database":true},"id":1}'),
(2,
3,
'roof',
181.00725895629216,
'2021-07-20T09:56:10.007+02:00',
'2021-07-20T09:56:10.007+02:00',
'{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[coords...]]]},"properties":{"UIDN":6338518,"OIDN":5290131,"VERSIE":1,"BEGINDATUM":"2015-09-23","VERSDATUM":"2015-09-23","TYPE":1,"LBLTYPE":"hoofdgebouw","OPNDATUM":"2015-08-25","BGNINV":5,"LBLBGNINV":"kadastralisatie","type":"roof","tools":"polygon","description":"D2","id":5290131,"area":181.00725895629216,"roofType":"flat","roofGreen":"normal","database":true},"id":2}'),
(3,
3,
'roof',
24.450163203958745,
'2021-07-20T09:56:10.007+02:00',
'2021-07-20T09:56:10.007+02:00',
'{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[coords...]]]},"properties":{"UIDN":5473377,"OIDN":4708120,"VERSIE":1,"BEGINDATUM":"2014-07-04","VERSDATUM":"2014-07-04","TYPE":2,"LBLTYPE":"bijgebouw","OPNDATUM":"2014-05-27","BGNINV":4,"LBLBGNINV":"bijhouding binnengebieden","type":"roof","tools":"polygon","description":"D3","id":4708120,"area":24.450163203958745,"roofType":"saddle","roofGreen":"normal","database":true},"id":3}'),
(4,
3,
'water',
57.65676046589426,
'2021-07-20T09:56:10.007+02:00',
'2021-07-20T09:56:10.007+02:00',
'{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[coords...]]]},"properties":{"UIDN":473256,"OIDN":199890,"VERSIE":2,"BEGINDATUM":"2017-03-08","VERSDATUM":"2021-05-06","VHAG":-9,"NAAM":"nvt","OPNDATUM":"2017-01-30","BGNINV":4,"LBLBGNINV":"bijhouding binnengebieden","type":"water","tools":"polygon","description":"W1","id":199890,"area":57.65676046589426,"waterType":"natural","database":true},"id":4}'))
AS v ("feature_id",
"plot_id",
"type",
"area",
"created_on",
"updated_on",
"geo_feature")
WHERE
v.feature_id = t.feature_id
INSERT INTO "features" ("plot_id", "type", "area", "created_on", "updated_on", "geo_feature")
values(3, 'roof', 342.01520314642977, '2021-07-20T10:17:04.565+02:00', '2021-07-20T10:17:04.565+02:00', '{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[coords...]]]},"properties":{"UIDN":6338864,"OIDN":5290477,"VERSIE":1,"BEGINDATUM":"2015-09-23","VERSDATUM":"2015-09-23","TYPE":1,"LBLTYPE":"hoofdgebouw","OPNDATUM":"2015-08-25","BGNINV":5,"LBLBGNINV":"kadastralisatie","type":"roof","tools":"polygon","description":"D1","id":5290477,"area":342.01520314642977,"roofType":"saddle","roofGreen":"normal","database":true},"id":1}'), (3, 'roof', 181.00725895629216, '2021-07-20T10:17:04.565+02:00', '2021-07-20T10:17:04.565+02:00', '{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[coords...]]]},"properties":{"UIDN":6338518,"OIDN":5290131,"VERSIE":1,"BEGINDATUM":"2015-09-23","VERSDATUM":"2015-09-23","TYPE":1,"LBLTYPE":"hoofdgebouw","OPNDATUM":"2015-08-25","BGNINV":5,"LBLBGNINV":"kadastralisatie","type":"roof","tools":"polygon","description":"D2","id":5290131,"area":181.00725895629216,"roofType":"flat","roofGreen":"normal","database":true},"id":2}'), (3, 'roof', 24.450163203958745, '2021-07-20T10:17:04.565+02:00', '2021-07-20T10:17:04.565+02:00', '{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[coords...]]]},"properties":{"UIDN":5473377,"OIDN":4708120,"VERSIE":1,"BEGINDATUM":"2014-07-04","VERSDATUM":"2014-07-04","TYPE":2,"LBLTYPE":"bijgebouw","OPNDATUM":"2014-05-27","BGNINV":4,"LBLBGNINV":"bijhouding binnengebieden","type":"roof","tools":"polygon","description":"D3","id":4708120,"area":24.450163203958745,"roofType":"saddle","roofGreen":"normal","database":true},"id":3}'), (3, 'water', 57.65676046589426, '2021-07-20T10:17:04.565+02:00', '2021-07-20T10:17:04.565+02:00', '{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[coords...]]]},"properties":{"UIDN":473256,"OIDN":199890,"VERSIE":2,"BEGINDATUM":"2017-03-08","VERSDATUM":"2021-05-06","VHAG":-9,"NAAM":"nvt","OPNDATUM":"2017-01-30","BGNINV":4,"LBLBGNINV":"bijhouding binnengebieden","type":"water","tools":"polygon","description":"W1","id":199890,"area":57.65676046589426,"waterType":"natural","database":true},"id":4}')
Your columns created_on and updated_on need SQL type casting, hence the error.
And there is no need re-creting the same list of table -> columns.
In all, your column-sets can be created like this:
const insertColumnSet = new pgp.helpers.ColumnSet([
'plot_id',
'type',
'area',
{name: 'created_on', cast: 'timestamptz'},
{name: 'updated_on', cast: 'timestamptz'},
'geo_feature'
], { table: 'features' });
const updateColumnSet = insertColumnSet.extend(['?feature_id']};
See Column full syntax, plus extend method.
UPDATE
Note that strictly speaking, only the UPDATE needs the type casting, while your INSERT can infer the type automatically, which you can reflect in the column-sets like this:
const insertColumnSet = new pgp.helpers.ColumnSet(['plot_id', 'type', 'area',
'created_on', 'updated_on', 'geo_feature'], { table: 'features' });
const updateColumnSet = insertColumnSet.merge([
{name: 'feature_id', cnd: true}, // or just '?feature_id'
{name: 'created_on', cast: 'timestamptz'},
{name: 'updated_on', cast: 'timestamptz'}
]};
Both approaches will work fine in your case though ;)
See merge method.

Break through Map

I would like to pass these params to server.
My problem is how can I loop through the map so can get the key and value to pass to server using http?
var map = json.decode(obj);
print(map);
Output
{material[0][name]: BRC, material[0][quantity]: 2, material[1][name]: BRC, material[1][quantity]: 11}
var data = jsonEncode({"material[0][name]": BRC, "material[0][quantity]": 2, "material[1][name]": BRC, "material[1][quantity]": 11, "material[2][name]": BRC, "material[2][quantity]": 11});
var response = await http.post(api_url, body: data, headers: {
'Accept': 'application/json',
"Content-Type": "application/json"
});

Leaflet Routing API: retrieve the legs data

I use the Leaflet Routing API, connected to Mapbox, to display a route with several waypoints.
Now, I have to retrieve the distance and the time between these waypoints for some calculations...
I see that the api.mapbox.com/directions API (called via Leaflet) receives as result an array of legs between my waypoints, and all data I need (legs'' distance and duration):
routes: [,…]
0: {legs: [{summary: "A 35, D 415", weight: 4813.6, duration: 4594.8,…},…], weight_name: "routability",…}
distance: 447598.9
duration: 22889.300000000003
legs: [{summary: "A 35, D 415", weight: 4813.6, duration: 4594.8,…},…]
0: {summary: "A 35, D 415", weight: 4813.6, duration: 4594.8,…}
distance: 101906.2
duration: 4594.8
steps: [{intersections: [{out: 0, entry: [true], bearings: [301], location: [7.761832, 48.592052]},…],…},…]
summary: "A 35, D 415"
1: {summary: "D 18bis, D 1bis", weight: 2070.1, duration: 1890.6,…}
distance: 28743.3
duration: 1890.6
steps: [{intersections: [{out: 0, entry: [true], bearings: [310], location: [7.538932, 47.928985]}],…},…]
summary: "D 18bis, D 1bis"
weight: 2070.1
2: {summary: "D 83, N 66", weight: 5097, duration: 4510.1,…}
...
I catch this result with a "routesfound" event, but I don't retrieve the legs from the result set:
{route: {…}, alternatives: Array(0), type: "routeselected", target: e, sourceTarget: e}
alternatives: []
route:
coordinates: (8188) [M, M, M, M, M, M, M, M, …]
inputWaypoints: (6) [e, e, e, e, e, e]
instructions: (104) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, …]
name: "A 35, D 415, D 18bis, D 1bis, D 83, N 66, Rue du Ballon d'Alsace, D 465, La Comtoise, L'Alsacienne"
properties: {isSimplified: true}
routesIndex: 0
summary:
totalDistance: 447598.9
totalTime: 22889.300000000003
__proto__: Object
waypointIndices: (6) [0, 1611, 2100, 3485, 5808, 8187]
waypoints: (6) [e, e, e, e, e, e]
__proto__: Object
sourceTarget: e {options: {…}, _router: e, _plan: e, _requestCount: 1, _formatter: e, …}
target: e {options: {…}, _router: e, _plan: e, _requestCount: 1, _formatter: e, …}
type: "routeselected"
Is there a way to access the native result via Leaflet, or am I forced to do a duplicate call to the Mapbox API to bypass Leaflet ?
I have the same problem and I tried to get the response of the router. After digging into the code I found the _pendingRequest that hold the router XML HTTP request
ACTIVE_DAY_ROUTE = L.Routing.control({
show: false,
waypoints: routeWaypoints,
router: ROUTER,
routeWhileDragging: false,
draggableWaypoints: false,
lineOptions: {
styles: [{
color: ROUTE_COLOR,
opacity: ROUTE_OPACITY,
weight: 4
}]
},
createMarker: function() {
return null;
}
});
console.log(ACTIVE_DAY_ROUTE._pendingRequest.response);
I succeed to get it on console.log but can't get the response attribute (perhaps because it is pending or finished when I try to get the value)
UPDATE:
I hacked the _convertRoute method to include legs in it
var result = {
name: '',
coordinates: [],
instructions: [],
legs: '', // HACK HERE
summary: {
totalDistance: responseRoute.distance,
totalTime: responseRoute.duration
}
},
result.legs = responseRoute.legs; // HACK HERE - Affect leg

Google Charts: ChartWrapper and Formatters (NumberFormat)

How do I use ChartWrapper and a formatter to add a suffix to the tooltip on line / bar charts?
This is my code for the ChartWrapper
function drawChartb() {
var wrapper = new google.visualization.ChartWrapper({
chartType: 'LineChart',
dataTable: [['Person', 'Score'], [1, .50], [2, .25]],
options: {'legend': 'bottom', 'colors': ['#D70005'], 'chartArea': {left: 40, top: 10, width: 450}, 'vAxis': {format: '#,###%', 'viewWindow': {max: 1.05, min: .2}}, 'pointSize': 6},
containerId: 'chart_div'
});
wrapper.draw();
}
This is how I did it without using a chartwrapper.
// set tooltip as percentage
var formatter = new google.visualization.NumberFormat({
pattern: '#%',
fractionDigits: 2
});
formatter.format(data, 1);
Thanks
You can define your data outside the wrapper, use the formatter on it, and then set the dataTable to be equal to that data source:
function drawVisualization() {
var data = google.visualization.arrayToDataTable([
['Person', 'Score'], [1, .50], [2, .25]
]);
// set tooltip as percentage
var formatter = new google.visualization.NumberFormat({
pattern: '#%',
fractionDigits: 2
});
formatter.format(data, 1);
var wrapper = new google.visualization.ChartWrapper({
chartType: 'LineChart',
dataTable: data,
options: {'legend': 'bottom', 'colors': ['#D70005'], 'chartArea': {left: 40, top: 10, width: 450}, 'vAxis': {format: '#,###%', 'viewWindow': {max: 1.05, min: .2}}, 'pointSize': 6},
containerId: 'visualization'
});
wrapper.draw();
}
Result:
For those who generate their chart data using Google JSON schema and cannot get NumberFormat to work with ChartWrapper, you can apply formatting directly to the row "f":null
To note:
I have found the NumberFormat constructor method works with DataTables but not with ChartWrapper.
Using DataTable > OK
var chart = new google.visualization.PieChart(document.getElementById('chart'));
var dataTable = new google.visualization.DataTable(data);
var formatter = new google.visualization.NumberFormat({prefix: '$'});
formatter.format(dataTable, 1);
Using ChartWrapper > BAD
var formatter = new google.visualization.NumberFormat({prefix: '$'});
formatter.format(data, 1);
var wrapper = new google.visualization.ChartWrapper({
chartType: 'PieChart',
dataTable: data,
options: myPieChartOptions(),
containerId: 'chart_div'
});
This is how I properly formatted my data using Google JSON.
Example JSON:
{
"cols": [
{"id":"","label":"Product","pattern":"","type":"string"},
{"id":"","label":"Sales","pattern":"","type":"number"}
],
"rows": [
{"c":[{"v":"Nuts","f":null},{"v":945.59080870918,"f":"$945.59"}]}
]
}
And here's the PHP code to generate that JSON
setlocale(LC_MONETARY, 0);
// init arrays
$result['cols'] = array();
$result['rows'] = array();
// add col data
$result['cols'][] = array(
"id" => "",
"label" => "Product",
"pattern" => "",
"type" => "string"
);
$result['cols'][] = array(
"id" => "",
"label" => "Sales",
"pattern" => "",
"type" => "number"
);
$nutsTotalFormat = "$".number_format($nutsTotal, 2);
$result['rows'][]["c"] = array(array("v" => "Nuts","f" => null),array("v" => $nutsTotal,"f" => $nutsTotalFormat ));
Pie chart will show the formatted result of $nutsTotalFormat
"$945.59"