forked from Novartis/xgx
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Data.cpp
162 lines (156 loc) · 5.43 KB
/
Data.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include <Rcpp.h>
using namespace Rcpp;
//[[Rcpp::export]]
List dataEdaGen(DataFrame data,
std::string id="",
std::string evid="",
std::string time=""){
// This is to create
//
// 1. Time between dose and first observation after dose
// 2. Time between last obervation and next dose
// 3. Time between doses
//
// This function makes the following assumptions:
// a. The ID variable is specified by the varible id or is ID, Id, id
// b. The EVID variable is specified by the variable evid or is EVID Evid or evid
// - The EVID is 0 for observation records.
// - The EVID is !=r 0 for dosing records.
// c. The TIME variable is specified by the time or is TIME Time or time
int idi = -1, evidi=-1, timei=-1, i;
CharacterVector nm = data.names();
std::string cur;
// This gets the column number of ID, EVID and TIME columns
for (i = nm.size(); i--;){
cur = as<std::string>(nm[i]);
if (idi == -1 &&
((id == "" && (cur == "ID" || cur == "Id" || cur == "id")) ||
id == cur)){
idi = i;
} else if (evidi == -1 &&
((evid == "" && (cur == "EVID" || cur == "Evid" || cur == "evid")) ||
evid == cur)){
evidi = i;
} else if (timei == -1 &&
((time == "" && (cur == "TIME" || cur == "Time" || cur == "time")) ||
time == cur)){
timei = i;
} else if (timei != -1 && evidi != -1 && idi != -1) break; // Found everything early exit.
}
if (timei == -1 || evidi == -1 || idi == -1) stop("Need time, evid and id variables.");
IntegerVector idv = as<IntegerVector>(data[idi]);
IntegerVector evidv = as<IntegerVector>(data[evidi]);
NumericVector timev = as<NumericVector>(data[timei]);
double lastObsTime = 1.0, lastDoseTime = -1.0;
int lastDosei = -1, lastObsi = -1;
int lastId=-1;
// II dataset
double* ii = Calloc(idv.size(),double);
int* iiId = Calloc(idv.size(),int);
int* iiRow1 = Calloc(idv.size(),int);
int* iiRow2 = Calloc(idv.size(),int);
// Dose->Observation dataest
double* dod = Calloc(idv.size(),double);
int* doId = Calloc(idv.size(),int);
int* doRow1 = Calloc(idv.size(),int);
int* doRow2 = Calloc(idv.size(),int);
// Observation->Dose dataset
double* odd = Calloc(idv.size(),double);
int* odId = Calloc(idv.size(),int);
int* odRow1 = Calloc(idv.size(),int);
int* odRow2 = Calloc(idv.size(),int);
unsigned int iii = 0, doi = 0, odi = 0;
bool lastDose = true;
for (i = idv.size(); i--;){
if (lastId != idv[i]){
lastObsTime = -1.0;
lastDoseTime = -1.0;
lastId = idv[i];
}
if (evidv[i] > 0){
// Dosing Event
if (lastDoseTime > 0){
// II dataset:
// ID II row1 row2
ii[iii] = lastDoseTime - timev[i] ;
iiId[iii] = idv[i];
iiRow1[iii] = (int)(i+1);
iiRow2[iii] = (int)(lastDosei+1);
++iii;
}
if (!lastDose && lastObsTime > 0){
// Dose->Observation
dod[doi] = lastObsTime - timev[i];
doId[doi] = idv[i];
doRow1[doi] = (int)(i+1);
doRow2[doi] = (int)(lastObsi+1);
++doi;
}
lastDoseTime = timev[i];
lastDosei = i;
lastDose = true;
} else {
// Observation Event
if (lastDose && lastDoseTime > 0){
// Observation -> Dose (this is a backward loop)
odd[odi] = lastDoseTime - timev[i];
odId[odi] = idv[i];
odRow1[odi] = (int)(i+1);
odRow2[odi] = (int)(lastDosei+1);
++odi;
}
lastObsTime = timev[i];
lastObsi = i;
lastDose = false;
}
}
List ret(3);
// Now create 3 datasets and return them as a list.
// II Dataset
NumericVector dfIIdouble = NumericVector(iii);
memcpy(&dfIIdouble[0],ii, iii*sizeof(double));
Free(ii);
IntegerVector dfIIId = IntegerVector(iii);
memcpy(&dfIIId[0], iiId, iii*sizeof(int));
Free(iiId);
IntegerVector dfIIRow1 = IntegerVector(iii);
memcpy(&dfIIRow1[0], iiRow1, iii*sizeof(int));
Free(iiRow1);
IntegerVector dfIIRow2 = IntegerVector(iii);
memcpy(&dfIIRow2[0], iiRow2, iii*sizeof(int));
Free(iiRow2);
DataFrame dfII = DataFrame::create(_["ID"] = dfIIId, _["II"] = dfIIdouble, _["row1"] = dfIIRow1, _["row2"] = dfIIRow2);
ret[0] = dfII;
// DO dataset
NumericVector dfDOdouble = NumericVector(doi);
memcpy(&dfDOdouble[0],dod, doi*sizeof(double));
Free(dod);
IntegerVector dfDOId = IntegerVector(doi);
memcpy(&dfDOId[0], doId, doi*sizeof(int));
Free(doId);
IntegerVector dfDORow1 = IntegerVector(doi);
memcpy(&dfDORow1[0], doRow1, doi*sizeof(int));
Free(doRow1);
IntegerVector dfDORow2 = IntegerVector(doi);
memcpy(&dfDORow2[0], doRow2, doi*sizeof(int));
Free(doRow2);
DataFrame dfDO = DataFrame::create(_["ID"] = dfDOId, _["DO"] = dfDOdouble, _["row1"] = dfDORow1, _["row2"] = dfDORow2);
ret[1] = dfDO;
// OD dataset
NumericVector dfODoduble = NumericVector(odi);
memcpy(&dfODoduble[0],odd, odi*sizeof(double));
Free(odd);
IntegerVector dfODId = IntegerVector(odi);
memcpy(&dfODId[0], odId, odi*sizeof(int));
Free(odId);
IntegerVector dfODRow1 = IntegerVector(odi);
memcpy(&dfODRow1[0], odRow1, odi*sizeof(int));
Free(odRow1);
IntegerVector dfODRow2 = IntegerVector(odi);
memcpy(&dfODRow2[0], odRow2, odi*sizeof(int));
Free(odRow2);
DataFrame dfOD = DataFrame::create(_["ID"] = dfODId, _["OD"] = dfODoduble, _["row1"] = dfODRow1, _["row2"] = dfODRow2);
ret[2] = dfOD;
ret.attr("names") = CharacterVector::create("II","DO","OD");
return ret;
}