Skip to content

Commit e21cb03

Browse files
author
Keith Goldfeld
committed
Updating addPeriods
1 parent 8d1fd44 commit e21cb03

File tree

4 files changed

+94
-26
lines changed

4 files changed

+94
-26
lines changed

NEWS.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# simstudy (development version)
22

33
## New features
4-
*`addPeriods` has a new argument `periodVec` that allows user to specify
5-
specific measurement time periods as a vector.
4+
*`addPeriods` now includes a new argument `periodVec` that allows users to designate
5+
specific measurement time periods using vector.
66

77
## Minor fix
88
* Function `logisticCoefs` now correctly handles double dot notation.

R/group_data.R

+20-18
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,25 @@
88
#' @param timevarName Name of new time dependent variable
99
#' @param timeid Variable name for new index field. Defaults to "timevar"
1010
#' @param perName Variable name for period field. Defaults to "period"
11-
#' @param perVec Vector of period times. Defaults to NULL
11+
#' @param periodVec Vector of period times. Defaults to NULL
1212
#' @details It is possible to generate longitudinal data with varying
1313
#' numbers of measurement periods as well as varying time intervals between
1414
#' each measurement period. This is done by defining specific variables \emph{in} the
1515
#' data set that define the number of observations per subject and the average
1616
#' interval time between each observation. \bold{\emph{nCount}} defines the number of
1717
#' measurements for an individual; \bold{\emph{mInterval}} specifies the average time between
18-
#' intervals for a subject; and vInterval specifies the variance of those
19-
#' interval times. If \bold{\emph{vInterval}} is set to 0 or is not defined, the interval for
18+
#' intervals for a subject; and \bold{\emph{vInterval}} specifies the variance of those
19+
#' interval times. If \bold{\emph{mInterval}} is not defined, no intervals are used. If \bold{\emph{vInterval}} is set to 0 or is not defined, the interval for
2020
#' a subject is determined entirely by the mean interval. If \bold{\emph{vInterval}} is
2121
#' greater than 0, time intervals are generated using a gamma distribution
2222
#' with specified mean and dispersion. If either \bold{\emph{nPeriods}} or \bold{\emph{timevars}}
2323
#' is specified, that will override any \bold{\emph{nCount}}, \bold{\emph{mInterval}}, and
2424
#' \bold{\emph{vInterval}} data.
2525
#'
26-
#' \bold\emph{{perVec}} is used to specify measurement periods that are different
27-
#' the default counting variables. If \bold\emph{{perVec}} is not specified,
26+
#' \bold{\emph{periodVec}} is used to specify measurement periods that are different
27+
#' the default counting variables. If \bold{\emph{periodVec}} is not specified,
2828
#' the periods default to \emph{0, 1, ... n-1}, with \emph{n} periods. If
29-
#' \bold\emph{{perVec}} is specified as \emph{c(x_1, x_2, ... x_n)}, then
29+
#' \bold{\emph{periodVec}} is specified as \emph{c(x_1, x_2, ... x_n)}, then
3030
#' \emph{x_1, x_2, ... x_n} represent the measurement periods.
3131
#' @return An updated data.table that that has multiple rows
3232
#' per observation in dtName
@@ -98,10 +98,13 @@ addPeriods <- function(dtName,
9898
if (!is.null(nPeriods)) { # same number for each subject
9999

100100
dtTimes1 <- dtX1[, list(.period = (0:(nPeriods - 1))), keyby = idvars]
101+
101102
} else {
103+
102104
if ("nCount" %in% names(dtX1)) { # specified for each subject
103105

104106
dtTimes1 <- dtX1[, list(.period = (0:(nCount - 1))), keyby = idvars]
107+
105108
} else { # not specified for each subject or for all
106109

107110
stop("No period or count parameter provided")
@@ -113,6 +116,12 @@ addPeriods <- function(dtName,
113116
data.table::setkeyv(dtX1, idvars)
114117
dtTimes1 <- dtTimes1[dtX1]
115118
data.table::setkeyv(dtTimes1, c(idvars, ".period"))
119+
120+
# Remove nCount if it was included
121+
122+
if ("nCount" %in% names(dtX1)) {
123+
dtTimes1[, nCount := NULL]
124+
}
116125

117126
# Create code for final index assignment
118127

@@ -152,14 +161,11 @@ addPeriods <- function(dtName,
152161
eval(cmd)
153162
data.table::setkeyv(dtTimes1, timeid)
154163

155-
data.table::setnames(dtTimes1, old = ".period", new = perName)
156-
157164
} else { # if time dependent variables not specified
158165

159166
eval(cmd)
160167
data.table::setkeyv(dtTimes1, timeid)
161168

162-
data.table::setnames(dtTimes1, old = ".period", new = perName)
163169
}
164170

165171
# if specified different measurement intervals:
@@ -169,30 +175,26 @@ addPeriods <- function(dtName,
169175
assertNumeric(periodVec = periodVec)
170176
assertLength(periodVec = periodVec, length = nPeriods) # Need to make sure
171177

172-
dtTimes1[, period := periodVec[period + 1]]
178+
dtTimes1[, .period := periodVec[.period + 1]]
173179
}
174180

175181
} else { # is.null(nPeriods) == TRUE
176182

177-
if (all(c("nCount", "mInterval") %in% names(dtX1))) {
183+
if ( "mInterval" %in% names(dtX1) ) {
178184
if (!("vInterval" %in% names(dtX1))) dtTimes1[, vInterval := 0]
179185

180186
dtTimes1[, timeElapsed := .genPosSkew(1, mInterval, vInterval), keyby = c(idvars, ".period")]
181187
dtTimes1[.period == 0, timeElapsed := 0]
182188

183189
dtTimes1[, time := round(cumsum(timeElapsed)), keyby = idvars]
184-
dtTimes1[, c("timeElapsed", "nCount", "mInterval", "vInterval") := NULL]
190+
dtTimes1[, c("timeElapsed", "mInterval", "vInterval") := NULL]
185191

186192
eval(cmd)
187193
data.table::setkeyv(dtTimes1, timeid)
188-
189-
data.table::setnames(dtTimes1, old = ".period", new = perName)
190-
191-
} else {
192-
stop("No period or count parameter provided")
193-
}
194+
}
194195
}
195196

197+
data.table::setnames(dtTimes1, old = ".period", new = perName)
196198
dtTimes1[]
197199

198200
}

man/addPeriods.Rd

+6-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-group_data.R

+66
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,69 @@
1+
# addPariods
2+
test_that("addPeriods works", {
3+
skip_on_cran()
4+
5+
tdef <- defData(varname = "T", dist = "binary", formula = 0.5)
6+
tdef <- defData(tdef, varname = "Y0", dist = "normal", formula = 10, variance = 1)
7+
tdef <- defData(tdef, varname = "Y1", dist = "normal", formula = "Y0 + 5 + 5 * T", variance = 1)
8+
tdef <- defData(tdef, varname = "Y2", dist = "normal", formula = "Y0 + 10 + 5 * T", variance = 1)
9+
10+
n <- ceiling(runif(1, 10, 20))
11+
dtTrial <- genData(n, tdef)
12+
13+
p <- ceiling(runif(1, 3, 8))
14+
dtTime <- addPeriods(
15+
dtTrial,
16+
nPeriods = p, idvars = "id"
17+
)
18+
19+
expect_equal(nrow(dtTime), n*p)
20+
21+
expect_silent(
22+
addPeriods(dtTrial,
23+
nPeriods = 3, idvars = "id",
24+
timevars = c("Y0", "Y1", "Y2"), timevarName = "Y",
25+
periodVec = c(0, 3, 5)
26+
)
27+
)
28+
29+
expect_warning(
30+
addPeriods(dtTrial,
31+
nPeriods = 2, idvars = "id",
32+
timevars = c("Y0", "Y1", "Y2"), timevarName = "Y"
33+
)
34+
)
35+
36+
testthat::expect_silent(
37+
addPeriods(dtTrial,
38+
nPeriods = 3, idvars = "id",
39+
timevars = c("Y0", "Y1", "Y2"),
40+
timevarName = "Y"
41+
)
42+
)
43+
44+
def <- defData(varname = "xbase", dist = "normal", formula = 20, variance = 3)
45+
def <- defData(def, varname = "nCount", dist = "noZeroPoisson", formula = 6)
46+
def <- defData(def, varname = "mInterval", dist = "gamma", formula = 30, variance = .01)
47+
def <- defData(def, varname = "vInterval", dist = "nonrandom", formula = .07)
48+
49+
dt <- genData(50, def)
50+
expect_silent(addPeriods(dt))
51+
52+
53+
def <- defData(varname = "xbase", dist = "normal", formula = 20, variance = 3)
54+
def <- defData(def, varname = "nCount", dist = "noZeroPoisson", formula = 6)
55+
def <- defData(def, varname = "mInterval", dist = "gamma", formula = 30, variance = .01)
56+
57+
dt <- genData(50, def)
58+
expect_silent(addPeriods(dt))
59+
60+
def <- defData(varname = "xbase", dist = "normal", formula = 20, variance = 3)
61+
62+
dt <- genData(50, def)
63+
expect_error(addPeriods(dt))
64+
65+
})
66+
167
# .addStrataCode ----
268
test_that("strata codes are added as expected.", {
369
skip_on_cran()

0 commit comments

Comments
 (0)