24
24
# ' @param levels the number of levels of the treatment.
25
25
# ' @param n effective sample size, default is NULL.
26
26
# ' @param treat.prob default is 0.5.
27
- # ' @param sims number of simulation runs to compute the expected type M error ("exaggeration ratio"), default 100k. If NULL, E(type M) is not computed.
27
+ # ' @param sims number of simulation runs to compute the expected type M error ("exaggeration ratio"), default 100k. If NULL or , E(type M) is not computed (much faster) .
28
28
# ' @keywords conjoint, power analysis, AMCE
29
29
# ' @export
30
30
# ' @export
31
31
# ' @export
32
32
# ' @export
33
33
# ' @examples
34
34
# ' # This gives the minimum required effective sample size (type S, E(type M)):
35
- # ' df = cjpowr_amce(amce = 0.05, power = 0.8, levels = 5)
35
+ # ' df <- cjpowr_amce(amce = 0.05, power = 0.8, levels = 5)
36
36
# '
37
37
# ' # For example, for a conjoint with 2 profiles and 4 tasks, n becomes:
38
38
# '
39
- # ' df$n/(2* 4)
39
+ # ' df$n / (2 * 4)
40
40
# '
41
- # ' #This gives the power (type S, E(type M)):
41
+ # ' # This gives the power (type S, E(type M)):
42
42
# ' cjpowr_amce(amce = 0.05, n = 7829.258, levels = 5)
43
43
# '
44
- # ' #Generating an interactive plot for type M error:
44
+ # ' # Generating an interactive plot for type M error:
45
45
# '
46
- # ' d <- expand.grid(amce = c(0.01, 0.02, 0.03, 0.05), n = seq(from = 100, to = 50000, length.out = 1000))
46
+ # ' d <- expand.grid(
47
+ # ' amce = c(0.01, 0.02, 0.03, 0.05),
48
+ # ' n = seq(from = 100, to = 50000, length.out = 1000),
49
+ # ' alpha = 0.05,
50
+ # ' levels = 2,
51
+ # ' treat.prob = 0.5,
52
+ # ' sims = 10000) #set to 0 if you want to make an interactive plot for something other than Type M error
47
53
# '
48
- # ' # Purrr Style:
49
- # ' library(purrr)
50
- # ' set.seed(123)
51
- # ' df <- pmap_df(d, function(amce, n) cjpowr_amce(amce = amce, n = n, sims = 1000, levels = 5, alpha = 0.05, treat.prob = 0.5))
52
- # '
53
- # ' # Base R:
54
- # ' set.seed(123)
55
- # ' cjpowr_amce_vec <- Vectorize(cjpowr_amce)
56
- # ' df2 <- t(cjpowr_amce_vec(amce = d$amce, n = d$n, sims = 1000, levels = 5, alpha = 0.05, treat.prob = 0.5))
57
- # '
58
- # ' df2 <- data.frame(df2)
59
- # ' df2[] <- lapply(df2, unlist)
54
+ # ' df <- list2DF(do.call(cjpowr_amce, d))
60
55
# '
61
56
# ' library(plotly)
62
- # '
63
- # ' plot_ly(df, x = ~n, y = ~exp_typeM, type = 'scatter', mode = 'lines', linetype = ~amce) %>%
64
- # ' layout(
65
- # ' xaxis = list(title = "Effective Sample Size",
66
- # ' zeroline = F,
67
- # ' hoverformat = '.0f'),
68
- # ' yaxis = list(title = "Exaggeration Ratio",
69
- # ' range = c(0,10),
70
- # ' zeroline = F,
71
- # ' hoverformat = '.2f'),
72
- # ' legend=list(title=list(text='<b> AMCE </b>')),
73
- # ' hovermode = "x unified"
74
- # ' )
57
+ # '
58
+ # ' plot_ly(df, x = ~n, y = ~exp_typeM, type = "scatter", mode = "lines", linetype = ~amce) %>%
59
+ # ' layout(
60
+ # ' xaxis = list(
61
+ # ' title = "Effective Sample Size",
62
+ # ' zeroline = F,
63
+ # ' hoverformat = ".0f"
64
+ # ' ),
65
+ # ' yaxis = list(
66
+ # ' title = "Exaggeration Ratio",
67
+ # ' range = c(0, 10),
68
+ # ' zeroline = F,
69
+ # ' hoverformat = ".2f"
70
+ # ' ),
71
+ # ' legend = list(title = list(text = "<b> AMCE </b>")),
72
+ # ' hovermode = "x unified"
73
+ # ' )
75
74
# ' @section Literature:
76
75
# '
77
76
# ' 1. Schuessler, J. and M. Freitag (2020). Power Analysis for Conjoint Experiments.
81
80
# ' British Journal of Mathematical and Statistical Psychology 72(1), 1–17.
82
81
83
82
cjpowr_amce <- function (amce , alpha = 0.05 , power = NULL , levels = 2 ,
84
- treat.prob = 0.5 , n = NULL , sims = 100000 ){
85
-
86
- if (sum(sapply(list (power ,n ), is.null )) != 1 )
83
+ treat.prob = 0.5 , n = NULL , sims = 100000 ) {
84
+ if (sum(sapply(list (power , n ), is.null )) != 1 ) {
87
85
stop(" either 'n' or 'power' must be provided" )
88
- if (! is.null(alpha ) && ! is.numeric(alpha ) || any(0 > alpha | alpha > 1 ))
86
+ }
87
+ if (! is.null(alpha ) && ! is.numeric(alpha ) || any(0 > alpha | alpha > 1 )) {
89
88
stop(" 'sig.level' must be numeric in [0, 1]" )
89
+ }
90
90
91
- if (is.null(sims )) {
91
+ lengths <- c(length(amce ), length(alpha ), length(power ), length(levels ), length(treat.prob ), length(n ), length(sims ))
92
+ non_null_lengths <- lengths [lengths > 0 ]
92
93
93
- if (is.null(n )) {
94
+ if (length(unique(non_null_lengths )) > 1 ) {
95
+ stop(" All non-NULL input parameters must be of the same length." )
96
+ }
94
97
95
- if (all(sapply(list (length(amce ), length(alpha ), length(power ), length(levels )), function (x ) x == 1 )) == FALSE ) {
96
- stop(" Please provide scalar values or apply a functional." )
97
- }
98
+ length_output <- unique(non_null_lengths )
98
99
99
- delta0 = 0.5 - (amce * treat.prob )
100
+ if (is.null(sims ) | any(sims == 0 ) == TRUE ) {
101
+ if (is.null(n )) {
102
+ delta0 <- 0.5 - (amce * treat.prob )
100
103
101
- n = (levels / 2 ) / (amce ^ 2 ) * (qnorm(p = 1 - alpha / 2 ) + qnorm(p = power ))^ 2 *
104
+ n <- (levels / 2 ) / (amce ^ 2 ) * (qnorm(p = 1 - alpha / 2 ) + qnorm(p = power ))^ 2 *
102
105
(
103
- ((delta0 + amce )* (1 - (delta0 + amce )))/ 0.5 +
104
- ((delta0 )* (1 - delta0 ))/ 0.5
106
+ ((delta0 + amce ) * (1 - (delta0 + amce ))) / 0.5 +
107
+ ((delta0 ) * (1 - delta0 )) / 0.5
105
108
)
106
109
107
- se = (sqrt( (
108
- ((delta0 + amce )* (1 - (delta0 + amce )))/ 0.5 +
109
- ((delta0 )* (1 - delta0 ))/ 0.5
110
- ))/ sqrt(2 * ( n / levels )))
110
+ se <- (sqrt((
111
+ ((delta0 + amce ) * (1 - (delta0 + amce ))) / 0.5 +
112
+ ((delta0 ) * (1 - delta0 )) / 0.5
113
+ )) / sqrt(2 * ( n / levels )))
111
114
112
- z = amce / se
115
+ z <- amce / se
113
116
114
- pow = pnorm(z - qnorm(1 - alpha / 2 )) + pnorm(- z - qnorm(1 - alpha / 2 ))
117
+ pow <- pnorm(z - qnorm(1 - alpha / 2 )) + pnorm(- z - qnorm(1 - alpha / 2 ))
115
118
116
- type_s = pnorm(- z - qnorm(1 - alpha / 2 ))/ pow
119
+ type_s <- pnorm(- z - qnorm(1 - alpha / 2 )) / pow
117
120
118
- return (data.frame (amce = amce , n = n , type_s = type_s , power = power , alpha = alpha , levels = levels , delta0 = delta0 ))
121
+ return (data.frame (amce = amce , n = n , type_s = type_s , power = power , alpha = alpha , levels = levels , delta0 = delta0 ))
119
122
}
120
123
121
124
else if (is.null(power )) {
125
+ delta0 <- 0.5 - (amce * treat.prob )
122
126
123
- if (all(sapply(list (length(amce ), length(alpha ), length(n ), length(levels )), function (x ) x == 1 )) == FALSE ) {
124
- stop(" Please provide scalar values or apply a functional." )
125
- }
127
+ se <- (sqrt((
128
+ ((delta0 + amce ) * (1 - (delta0 + amce ))) / 0.5 +
129
+ ((delta0 ) * (1 - delta0 )) / 0.5
130
+ )) / sqrt(2 * (n / levels )))
126
131
127
- delta0 = 0.5 - ( amce * treat.prob )
132
+ z <- amce / se
128
133
129
- se = (sqrt( (
130
- ((delta0 + amce )* (1 - (delta0 + amce )))/ 0.5 +
131
- ((delta0 )* (1 - delta0 ))/ 0.5
132
- ))/ sqrt(2 * (n / levels )))
134
+ power <- pnorm(z - qnorm(1 - alpha / 2 )) + pnorm(- z - qnorm(1 - alpha / 2 ))
133
135
134
- z = amce / se
136
+ type_s <- pnorm( - z - qnorm( 1 - alpha / 2 )) / power
135
137
136
- power = pnorm(z - qnorm(1 - alpha / 2 )) + pnorm(- z - qnorm(1 - alpha / 2 ))
137
-
138
- type_s = pnorm(- z - qnorm(1 - alpha / 2 ))/ power
139
-
140
- return (data.frame (power = power , type_s = type_s , amce = amce , n = n , alpha = alpha , levels = levels , delta0 = delta0 ))
138
+ return (data.frame (power = power , type_s = type_s , amce = amce , n = n , alpha = alpha , levels = levels , delta0 = delta0 ))
141
139
}
142
140
}
143
141
else if (is.null(n )) {
142
+ delta0 <- 0.5 - (amce * treat.prob )
144
143
145
- if (all(sapply(list (length(amce ), length(alpha ), length(power ), length(levels )), function (x ) x == 1 )) == FALSE ) {
146
- stop(" Please provide scalar values or apply a functional." )
147
- }
148
-
149
- delta0 = 0.5 - (amce * treat.prob )
150
-
151
- n = (levels / 2 )/ (amce ^ 2 ) * (qnorm(p = 1 - alpha / 2 ) + qnorm(p = power ))^ 2 *
144
+ n <- (levels / 2 ) / (amce ^ 2 ) * (qnorm(p = 1 - alpha / 2 ) + qnorm(p = power ))^ 2 *
152
145
(
153
- ((delta0 + amce )* (1 - (delta0 + amce )))/ 0.5 +
154
- ((delta0 )* (1 - delta0 ))/ 0.5
146
+ ((delta0 + amce ) * (1 - (delta0 + amce ))) / 0.5 +
147
+ ((delta0 ) * (1 - delta0 )) / 0.5
155
148
)
156
149
157
- se = (sqrt( (
158
- ((delta0 + amce )* (1 - (delta0 + amce )))/ 0.5 +
159
- ((delta0 )* (1 - delta0 ))/ 0.5
160
- ))/ sqrt(2 * ( n / levels )))
150
+ se <- (sqrt((
151
+ ((delta0 + amce ) * (1 - (delta0 + amce ))) / 0.5 +
152
+ ((delta0 ) * (1 - delta0 )) / 0.5
153
+ )) / sqrt(2 * ( n / levels )))
161
154
162
- z = amce / se
155
+ z <- amce / se
163
156
164
- pow = pnorm(z - qnorm(1 - alpha / 2 )) + pnorm(- z - qnorm(1 - alpha / 2 ))
157
+ pow <- pnorm(z - qnorm(1 - alpha / 2 )) + pnorm(- z - qnorm(1 - alpha / 2 ))
165
158
166
- type_s = pnorm(- z - qnorm(1 - alpha / 2 ))/ pow
159
+ type_s <- pnorm(- z - qnorm(1 - alpha / 2 )) / pow
167
160
168
- est <- amce + se * rnorm( sims )
161
+ exp_typeM <- vector( mode = " numeric " , length = length_output )
169
162
170
- sig <- abs(est ) > se * qnorm(1 - alpha / 2 )
163
+ for (i in seq(1 , length_output )) {
164
+ est <- amce [i ] + se [i ] * rnorm(sims [i ])
171
165
172
- exp_typeM <- abs(mean(abs( est )[ sig ]) / amce )
166
+ sig <- abs(est ) > se [ i ] * qnorm( 1 - alpha [ i ] / 2 )
173
167
174
- return (data.frame (n = n , type_s = type_s , exp_typeM = exp_typeM , amce = amce , power = power , alpha = alpha , levels = levels , delta0 = delta0 ))
168
+ exp_typeM [i ] <- abs(mean(abs(est )[sig ]) / amce [i ])
169
+ }
175
170
171
+ return (data.frame (n = n , type_s = type_s , exp_typeM = exp_typeM , amce = amce , power = power , alpha = alpha , levels = levels , delta0 = delta0 ))
176
172
}
177
173
178
- else if (is.null(power )){
174
+ else if (is.null(power )) {
175
+ delta0 <- 0.5 - (amce * treat.prob )
179
176
180
- if (all(sapply(list (length(amce ), length(alpha ), length(n ), length(levels )), function (x ) x == 1 )) == FALSE ) {
181
- stop(" Please provide scalar values or apply a functional." )
182
- }
183
-
184
- delta0 = 0.5 - (amce * treat.prob )
177
+ se <- (sqrt((
178
+ ((delta0 + amce ) * (1 - (delta0 + amce ))) / 0.5 +
179
+ ((delta0 ) * (1 - delta0 )) / 0.5
180
+ )) / sqrt(2 * (n / levels )))
185
181
186
- se = (sqrt( (
187
- ((delta0 + amce )* (1 - (delta0 + amce )))/ 0.5 +
188
- ((delta0 )* (1 - delta0 ))/ 0.5
189
- ))/ sqrt(2 * (n / levels )))
182
+ z <- amce / se
190
183
191
- z = amce / se
184
+ power <- pnorm( z - qnorm( 1 - alpha / 2 )) + pnorm( - z - qnorm( 1 - alpha / 2 ))
192
185
193
- power = pnorm( z - qnorm( 1 - alpha / 2 )) + pnorm(- z - qnorm(1 - alpha / 2 ))
186
+ type_s <- pnorm(- z - qnorm(1 - alpha / 2 )) / power
194
187
195
- type_s = pnorm( - z - qnorm( 1 - alpha / 2 )) / power
188
+ exp_typeM <- vector( mode = " numeric " , length = length_output )
196
189
197
- est <- amce + se * rnorm(sims )
190
+ for (i in seq(1 , length_output )) {
191
+ est <- amce [i ] + se [i ] * rnorm(sims [i ])
198
192
199
- sig <- abs(est ) > se * qnorm(1 - alpha / 2 )
193
+ sig <- abs(est ) > se [ i ] * qnorm(1 - alpha [ i ] / 2 )
200
194
201
- exp_typeM <- abs(mean(abs(est )[sig ])/ amce )
195
+ exp_typeM [i ] <- abs(mean(abs(est )[sig ]) / amce [i ])
196
+ }
202
197
203
- return (data.frame (power = power , type_s = type_s , exp_typeM = exp_typeM , amce = amce , n = n , alpha = alpha , levels = levels , delta0 = delta0 ))
198
+ return (data.frame (power = power , type_s = type_s , exp_typeM = exp_typeM , amce = amce , n = n , alpha = alpha , levels = levels , delta0 = delta0 ))
204
199
}
205
-
206
- }
200
+ }
0 commit comments