mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-14 16:39:57 +00:00
R GC.activity.meanmax()
.. returns a data.frame with meanmax arrays for the series that are present
This commit is contained in:
@@ -661,6 +661,24 @@ RideFileCache::meanMaxDates(RideFile::SeriesType series)
|
||||
}
|
||||
}
|
||||
|
||||
QList<RideFile::SeriesType> RideFileCache::meanMaxList()
|
||||
{
|
||||
QList<RideFile::SeriesType> list;
|
||||
list << RideFile::watts
|
||||
<< RideFile::wattsKg
|
||||
<< RideFile::nm
|
||||
<< RideFile::hr
|
||||
<< RideFile::cad
|
||||
<< RideFile::kph
|
||||
<< RideFile::vam
|
||||
<< RideFile::NP
|
||||
<< RideFile::aPower
|
||||
<< RideFile::xPower
|
||||
;
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
QVector<double> &
|
||||
RideFileCache::meanMaxArray(RideFile::SeriesType series)
|
||||
{
|
||||
|
||||
@@ -201,6 +201,7 @@ class RideFileCache
|
||||
static RideFileCache *createCacheFor(RideFile*);
|
||||
|
||||
// get data
|
||||
static QList<RideFile::SeriesType> meanMaxList(); // list of types available as meanmax arrays
|
||||
QVector<double> &meanMaxArray(RideFile::SeriesType); // return meanmax array for the given series
|
||||
QVector<QDate> &meanMaxDates(RideFile::SeriesType series); // the dates of the bests
|
||||
QVector<double> &distributionArray(RideFile::SeriesType); // return distribution array for the given series
|
||||
|
||||
207
src/R/RTool.cpp
207
src/R/RTool.cpp
@@ -23,6 +23,7 @@
|
||||
#include "RideCache.h"
|
||||
#include "RideItem.h"
|
||||
#include "RideFile.h"
|
||||
#include "RideFileCache.h"
|
||||
#include "Colors.h"
|
||||
#include "RideMetric.h"
|
||||
#include "RideMetadata.h"
|
||||
@@ -83,6 +84,7 @@ RTool::RTool()
|
||||
{ "GC.athlete.home", (DL_FUNC) &RTool::athleteHome, 0 ,0, 0 },
|
||||
{ "GC.activities", (DL_FUNC) &RTool::activities, 0 ,0, 0 },
|
||||
{ "GC.activity", (DL_FUNC) &RTool::activity, 0 ,0, 0 },
|
||||
{ "GC.activity.meanmax", (DL_FUNC) &RTool::activityMeanmax, 0 ,0, 0 },
|
||||
{ "GC.metrics", (DL_FUNC) &RTool::metrics, 0 ,0, 0 },
|
||||
{ "GC.pmc", (DL_FUNC) &RTool::pmc, 0 ,0, 0 },
|
||||
{ NULL, NULL, 0, 0, 0 }
|
||||
@@ -97,6 +99,7 @@ RTool::RTool()
|
||||
// currently in the compare pane if compare is enabled or
|
||||
// just a 1 item list with the current ride
|
||||
{ "GC.activity", (DL_FUNC) &RTool::activity, 1 },
|
||||
{ "GC.activity.meanmax", (DL_FUNC) &RTool::activityMeanmax, 1 },
|
||||
|
||||
// metrics is passed a Rboolean for "all":
|
||||
// TRUE -> return all metrics, FALSE -> apply date range selection
|
||||
@@ -124,6 +127,7 @@ RTool::RTool()
|
||||
"GC.athlete.home <- function() { .Call(\"GC.athlete.home\") }\n"
|
||||
"GC.activities <- function() { .Call(\"GC.activities\") }\n"
|
||||
"GC.activity <- function(compare=FALSE) { .Call(\"GC.activity\", compare) }\n"
|
||||
"GC.activity.meanmax <- function(compare=FALSE) { .Call(\"GC.activity.meanmax\", compare) }\n"
|
||||
"GC.metrics <- function(all=FALSE, compare=FALSE) { .Call(\"GC.metrics\", all, compare) }\n"
|
||||
"GC.pmc <- function(all=FALSE, metric=\"TSS\") { .Call(\"GC.pmc\", all, metric) }\n"
|
||||
"GC.version <- function() { return(\"%1\") }\n"
|
||||
@@ -821,6 +825,209 @@ RTool::activity(SEXP pCompare)
|
||||
return Rf_allocVector(INTSXP, 0);
|
||||
}
|
||||
|
||||
SEXP
|
||||
RTool::dfForActivityMeanmax(const RideItem *i)
|
||||
{
|
||||
// how many series and how big are they?
|
||||
unsigned int seriescount=0, size=0;
|
||||
|
||||
// get the meanmax array
|
||||
RideFileCache *cache = const_cast<RideItem*>(i)->fileCache();
|
||||
if (cache != NULL) {
|
||||
// how many points in the ridefilecache and how many series to return
|
||||
foreach(RideFile::SeriesType series, cache->meanMaxList()) {
|
||||
QVector <double> values = cache->meanMaxArray(series);
|
||||
if (values.count()) {
|
||||
size = values.count();
|
||||
seriescount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we return a list of series vectors
|
||||
SEXP ans;
|
||||
PROTECT(ans = Rf_allocList(seriescount));
|
||||
|
||||
// we collect the names as we go
|
||||
SEXP names;
|
||||
PROTECT(names = Rf_allocVector(STRSXP, seriescount)); // names attribute (column names)
|
||||
int next=0;
|
||||
SEXP nextS = ans;
|
||||
|
||||
//
|
||||
// Now we need to add vectors to the ans list...
|
||||
//
|
||||
|
||||
foreach(RideFile::SeriesType series, cache->meanMaxList()) {
|
||||
|
||||
QVector <double> values = cache->meanMaxArray(series);
|
||||
|
||||
// don't add empty ones
|
||||
if (values.count()==0) continue;
|
||||
|
||||
|
||||
// set a vector
|
||||
SEXP vector;
|
||||
PROTECT(vector=Rf_allocVector(REALSXP, size));
|
||||
|
||||
for(unsigned int j=0; j<size; j++) REAL(vector)[j] = values[j];
|
||||
|
||||
// add to the list
|
||||
SETCAR(nextS, vector);
|
||||
nextS = CDR(nextS);
|
||||
|
||||
// give it a name
|
||||
SET_STRING_ELT(names, next, Rf_mkChar(RideFile::seriesName(series, true).toLatin1().constData()));
|
||||
|
||||
next++;
|
||||
|
||||
// vector
|
||||
UNPROTECT(1);
|
||||
}
|
||||
|
||||
// add rownames
|
||||
SEXP rownames;
|
||||
PROTECT(rownames = Rf_allocVector(STRSXP, size));
|
||||
for(unsigned int i=0; i<size; i++) {
|
||||
QString rownumber=QString("%1").arg(i+1);
|
||||
SET_STRING_ELT(rownames, i, Rf_mkChar(rownumber.toLatin1().constData()));
|
||||
}
|
||||
|
||||
// turn the list into a data frame + set column names
|
||||
Rf_setAttrib(ans, R_RowNamesSymbol, rownames);
|
||||
Rf_setAttrib(ans, R_ClassSymbol, Rf_mkString("data.frame"));
|
||||
Rf_namesgets(ans, names);
|
||||
|
||||
// ans + names + rownames
|
||||
UNPROTECT(3);
|
||||
|
||||
// return a valid result
|
||||
return ans;
|
||||
}
|
||||
|
||||
SEXP
|
||||
RTool::activityMeanmax(SEXP pCompare)
|
||||
{
|
||||
// a dataframe to return
|
||||
SEXP ans=NULL;
|
||||
|
||||
// p1 - compare=TRUE|FALSE - return list of compare rides if active, or just current
|
||||
pCompare = Rf_coerceVector(pCompare, LGLSXP);
|
||||
bool compare = LOGICAL(pCompare)[0];
|
||||
|
||||
// return a list
|
||||
if (compare && rtool->context) {
|
||||
|
||||
|
||||
if (rtool->context->isCompareIntervals) {
|
||||
|
||||
// how many to return?
|
||||
int count=0;
|
||||
foreach(CompareInterval p, rtool->context->compareIntervals) if (p.isChecked()) count++;
|
||||
|
||||
// cool we can return a list of intervals to compare
|
||||
SEXP list;
|
||||
PROTECT(list=Rf_allocVector(LISTSXP, count));
|
||||
|
||||
// start at the front
|
||||
SEXP nextS = list;
|
||||
|
||||
// a named list with data.frame 'activity' and color 'color'
|
||||
SEXP namedlist;
|
||||
|
||||
// names
|
||||
SEXP names;
|
||||
PROTECT(names=Rf_allocVector(STRSXP, 2));
|
||||
SET_STRING_ELT(names, 0, Rf_mkChar("meanmax"));
|
||||
SET_STRING_ELT(names, 1, Rf_mkChar("color"));
|
||||
|
||||
// create a data.frame for each and add to list
|
||||
foreach(CompareInterval p, rtool->context->compareIntervals) {
|
||||
if (p.isChecked()) {
|
||||
|
||||
// create a named list
|
||||
PROTECT(namedlist=Rf_allocVector(LISTSXP, 2));
|
||||
SEXP offset = namedlist;
|
||||
|
||||
// add the ride
|
||||
SEXP df = rtool->dfForActivityMeanmax(p.rideItem);
|
||||
SETCAR(offset, df);
|
||||
offset=CDR(offset);
|
||||
|
||||
// add the color
|
||||
SEXP color;
|
||||
PROTECT(color=Rf_allocVector(STRSXP, 1));
|
||||
SET_STRING_ELT(color, 0, Rf_mkChar(p.color.name().toLatin1().constData()));
|
||||
SETCAR(offset, color);
|
||||
|
||||
// name them
|
||||
Rf_namesgets(namedlist, names);
|
||||
|
||||
// add to back and move on
|
||||
SETCAR(nextS, namedlist);
|
||||
nextS=CDR(nextS);
|
||||
|
||||
UNPROTECT(2);
|
||||
}
|
||||
}
|
||||
UNPROTECT(2); // list and names
|
||||
|
||||
return list;
|
||||
|
||||
} else if(rtool->context->currentRideItem() && const_cast<RideItem*>(rtool->context->currentRideItem())->ride()) {
|
||||
|
||||
// just return a list of one ride
|
||||
// cool we can return a list of intervals to compare
|
||||
SEXP list;
|
||||
PROTECT(list=Rf_allocVector(LISTSXP, 1));
|
||||
|
||||
// names
|
||||
SEXP names;
|
||||
PROTECT(names=Rf_allocVector(STRSXP, 2));
|
||||
SET_STRING_ELT(names, 0, Rf_mkChar("meanmax"));
|
||||
SET_STRING_ELT(names, 1, Rf_mkChar("color"));
|
||||
|
||||
// named list of activity and color
|
||||
SEXP namedlist;
|
||||
PROTECT(namedlist=Rf_allocVector(LISTSXP, 2));
|
||||
SEXP offset = namedlist;
|
||||
|
||||
// add the ride
|
||||
SEXP df = rtool->dfForActivityMeanmax(rtool->context->currentRideItem());
|
||||
SETCAR(offset, df);
|
||||
offset=CDR(offset);
|
||||
|
||||
// add the color
|
||||
SEXP color;
|
||||
PROTECT(color=Rf_allocVector(STRSXP, 1));
|
||||
SET_STRING_ELT(color, 0, Rf_mkChar("#FF00FF"));
|
||||
SETCAR(offset, color);
|
||||
|
||||
// name them
|
||||
Rf_namesgets(namedlist, names);
|
||||
|
||||
// add to back and move on
|
||||
SETCAR(list, namedlist);
|
||||
UNPROTECT(4);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
} else if (!compare) { // not compare, so just return a dataframe
|
||||
|
||||
// access via global as this is a static function
|
||||
if(rtool->context && rtool->context->currentRideItem() && const_cast<RideItem*>(rtool->context->currentRideItem())->ride()) {
|
||||
|
||||
// get as a data frame
|
||||
ans = rtool->dfForActivityMeanmax(rtool->context->currentRideItem());
|
||||
return ans;
|
||||
}
|
||||
}
|
||||
|
||||
// nothing to return
|
||||
return Rf_allocVector(INTSXP, 0);
|
||||
}
|
||||
|
||||
SEXP
|
||||
RTool::pmc(SEXP pAll, SEXP pMetric)
|
||||
{
|
||||
|
||||
@@ -45,9 +45,10 @@ class RTool {
|
||||
static SEXP athlete();
|
||||
static SEXP athleteHome();
|
||||
static SEXP activities();
|
||||
static SEXP activity(SEXP all);
|
||||
static SEXP activity(SEXP compare);
|
||||
static SEXP metrics(SEXP all, SEXP compare);
|
||||
static SEXP pmc(SEXP all, SEXP metric);
|
||||
static SEXP activityMeanmax(SEXP compare);
|
||||
|
||||
bool starting;
|
||||
bool failed;
|
||||
@@ -74,6 +75,7 @@ class RTool {
|
||||
|
||||
// return a dataframe for the ride passed
|
||||
SEXP dfForActivity(RideFile *f);
|
||||
SEXP dfForActivityMeanmax(const RideItem *i);
|
||||
SEXP dfForDateRange(bool all, DateRange range);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user