Skip to content

Commit

Permalink
updated documentation for v0.0.2 release
Browse files Browse the repository at this point in the history
  • Loading branch information
jhelvy committed Dec 9, 2020
1 parent c35d567 commit a5c8e63
Show file tree
Hide file tree
Showing 10 changed files with 284 additions and 42 deletions.
7 changes: 4 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Package: conjointTools
Title: Tools For Designing Conjoint Survey Experiments
Version: 0.0.1
Version: 0.0.2
Maintainer: John Helveston <john.helveston@gmail.com>
Date: 2020-11-25
Date: 2020-12-09
Authors@R: c(
person(given = "John",
family = "Helveston",
Expand All @@ -27,6 +27,7 @@ RoxygenNote: 7.1.1
Imports:
AlgDesign,
rlang,
logitr (>= 0.0.4)
utils,
logitr (>= 0.0.5)
Remotes:
jhelvy/logitr
24 changes: 20 additions & 4 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@

# conjointTools 0.0.2

Interactions!

## Summary of larger updates:

- Added support for creating interactions among variables
- Removed summary plot function to drop ggplot dependencies

## Summary of smaller updates:

- Added a few new examples on how to use the interactions argument.



# conjointTools 0.0.1

* Created new functions for creating different experiment designs:
- Created new functions for creating different experiment designs:
- Full factorial
- "D", "A", and "I" optimal designs
* Modified previous functions for creating a coded survey from a given experiment design
* Changed the output of the sampleSizer function to show the sample size (rather than the number of observations, which can be different since respondents may answer more than one choice question).
- Modified previous functions for creating a coded survey from a given experiment design
- Changed the output of the sampleSizer function to show the sample size (rather than the number of observations, which can be different since respondents may answer more than one choice question).

# conjointTools 0.0.0.9000

* Added a `NEWS.md` file to track changes to the package.
- Added a `NEWS.md` file to track changes to the package.
91 changes: 75 additions & 16 deletions R/sampleSizer.R
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,64 @@
#'
#' @param survey The choice survey data frame exported from the `makeSurvey()` function.
#' @param parNames A vector of the names of the parameters to be estimated in the model. Must be the same as the column names in the `survey` argument.
#' @param parTypes A vector determining the type of each variable: "c" for continuous, or "d" for discrete. Continuous variables will be linearly coded whereas discrete variables will be dummy coded with one level removed for identification. Defaults to `NULL`, in which case all parameters are coded as discrete.
#' @param parTypes A vector determining the type of each variable: "c" for continuous, or "d" for discrete. Continuous variables will be linearly coded whereas discrete variables will be dummy coded with one level removed for identification. Defaults to `NULL`, in which case all parameters are coded as "d" for discrete.
#' @param interactions A logical value for adding interactions between all parameters in `parNames`. Defaults to `FALSE`.
#' @param nbreaks The number of different sample size groups.
#' @param randPars A named vector whose names are the random parameters and values the distribution: `'n'` for normal or `'ln'` for log-normal. Defaults to `NULL`.
#' @param options A list of options to control the model estimation.
#' @return Returns a data frame of the standard error values for different sample sizes.
#' @export
#' @examples
#' \dontrun{
#' library(conjointTools)
#'
#' # A simple conjoint experiment about apples, with one attribute (price)
#' # modeled as continuous
#'
#' # Make the design of experiment
#' doe <- makeDoe(
#' levels = c(3, 3, 3),
#' varNames = c("price", "type", "freshness"),
#' type = "full"
#' )
#'
#' # Make the survey
#' survey <- makeSurvey(
#' doe = doe, # Design of experiment
#' nResp = 1000, # Total number of respondents (upper bound)
#' nAltsPerQ = 3, # Number of alternatives per question
#' nQPerResp = 6 # Number of questions per respondent
#' )
#'
#' # Compute sample sizes
#' results <- sampleSizer(
#' survey = survey,
#' parNames = c('price', 'type', 'freshness'),
#' parTypes = c('c', 'd', 'd'), # Set continuous vs. discrete variables
#' nbreaks = 10
#' )
#'
#' # Preview results
#' head(results)
#'
#' # Plot results
#' library(ggplot2)
#'
#' ggplot(results) +
#' geom_point(aes(x = size, y = se, color = coef),
#' fill = "white", pch = 21) +
#' scale_y_continuous(limits = c(0, NA)) +
#' labs(x = 'Number of observations',
#' y = 'Standard Error',
#' color = "Variable") +
#' theme_bw()
#' }
sampleSizer = function(survey, parNames = NULL, parTypes = NULL, nbreaks = 10,
randPars = NULL, options = list(message = FALSE)) {
# Add random choices to the survey
survey$choice <- generateChoices(survey)
# Set parNames
if (is.null(parNames)) {
parNames <- names(survey)[!grepl("ID", names(survey))]
parNames <- parNames[-which(parNames == "choice")]
}
# Set continuous or discrete parameter types
if (!is.null(parTypes)) {
cpars <- parNames[which(parTypes == "c")]
survey[,cpars] <- as.numeric(survey[,cpars])
}
sampleSizer = function(survey, parNames = NULL, parTypes = NULL,
interactions = FALSE, nbreaks = 10, randPars = NULL,
options = list(message = FALSE)) {
inputs <- setupInputs(survey, parNames, parTypes, interactions)
survey <- inputs$survey
parNames <- inputs$parNames
# Loop through subsets of different sample sizes
# In each iteration, estimate a model and record the standard errors
maxObs <- max(survey['obsID'])
Expand All @@ -57,7 +92,31 @@ sampleSizer = function(survey, parNames = NULL, parTypes = NULL, nbreaks = 10,
return(do.call(rbind, standardErrors))
}

generateChoices <- function(survey) {
setupInputs <- function(survey, parNames, parTypes, interactions) {
# Set parNames
if (is.null(parNames)) {
parNames <- names(survey)[!grepl("ID", names(survey))]
parNames <- parNames[-which(parNames == "choice")]
}
# Recode survey variables as continuous or discrete
if (!is.null(parTypes)) {
cpars <- parNames[which(parTypes == "c")]
dpars <- parNames[which(parTypes == "d")]
survey[,cpars] <- lapply(survey[cpars], as.numeric)
survey[,dpars] <- lapply(survey[dpars], as.factor)
}
# Add interactions
if (interactions) {
ints <- t(utils::combn(parNames, 2))
ints <- paste(ints[,1], ints[,2], sep = "*")
parNames <- c(parNames, ints)
}
# Add random choices to the survey
survey$choice <- generateChoices(survey, parNames, parTypes)
return(list(survey = survey, parNames = parNames))
}

generateChoices <- function(survey, parNames, parTypes) {
nrows <- table(survey['obsID'])
choices <- list()
for (i in 1:length(nrows)) {
Expand Down
8 changes: 7 additions & 1 deletion README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ This package contains tools for designing choice based conjoint survey experimen

The current version is not yet on CRAN, but you can install it from
Github using the **devtools** library:

```{r, eval=FALSE}
devtools::install_github("jhelvy/conjointTools")
```
Expand All @@ -44,12 +45,14 @@ library(conjointTools)
Use the `makeDoe()` function to create a design of experiment

Generate a full factorial design of experiment with three attributes, each with 2 levels:

```{r}
doe <- makeDoe(levels = c(2, 2, 2))
doe
```

You can also give your variables names based on the attributes. Here is an example of a full factorial design of experiment about apples:

```{r}
doe <- makeDoe(
levels = c(2, 2, 2),
Expand All @@ -59,6 +62,7 @@ doe
```

The `makeDoe()` function can also generate "D", "A", and "I" optimal fractional factorial designs:

```{r}
doe <- makeDoe(
levels = c(2, 2, 2),
Expand All @@ -79,6 +83,7 @@ doe <- makeDoe(
varNames = c("price", "type", "freshness")
)
```

```{r}
survey <- makeSurvey(
doe = doe, # Design of experiment
Expand Down Expand Up @@ -107,6 +112,7 @@ results <- sampleSizer(
survey = survey,
parNames = c('price', 'type', 'freshness'),
parTypes = c('c', 'd', 'd'), # Set continuous vs. discrete variables
interactions = TRUE, # Add interactions between each attribute
nbreaks = 10
)
Expand All @@ -133,7 +139,7 @@ ggplot(results) +
- Date First Written: *October 23, 2020*
- Most Recent Update: `r format(Sys.Date(), format="%B %d %Y")`
- License: [MIT](https://github.com/jhelvy/conjointTools/blob/master/LICENSE.md)
- [Latest Release](https://github.com/jhelvy/conjointTools/releases/latest): 0.0.1
- [Latest Release](https://github.com/jhelvy/conjointTools/releases/latest): 0.0.2

## Citation Information

Expand Down
29 changes: 15 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,18 +137,19 @@ results <- sampleSizer(
survey = survey,
parNames = c('price', 'type', 'freshness'),
parTypes = c('c', 'd', 'd'), # Set continuous vs. discrete variables
interactions = TRUE, # Add interactions between each attribute
nbreaks = 10
)

# Preview results
head(results)
#> size se coef
#> 1 100 0.09239510 price
#> 2 100 0.09404767 type_2
#> 3 100 0.09376153 freshness_2
#> 4 200 0.06612120 price
#> 5 200 0.06657439 type_2
#> 6 200 0.06603612 freshness_2
#> size se coef
#> 1 100 0.1611530 price
#> 2 100 0.3110412 type_2
#> 3 100 0.3118941 freshness_2
#> 4 100 0.1897302 price*type_2
#> 5 100 0.1887158 price*freshness_2
#> 6 100 0.1891048 type_2*freshness_2
```

View a plot of the results
Expand All @@ -170,12 +171,12 @@ ggplot(results) +
## Version and License Information

- Date First Written: *October 23, 2020*
- Most Recent Update: December 06 2020
- Most Recent Update: December 09 2020
- License:
[MIT](https://github.com/jhelvy/conjointTools/blob/master/LICENSE.md)
- [Latest
Release](https://github.com/jhelvy/conjointTools/releases/latest):
0.0.1
0.0.2

## Citation Information

Expand All @@ -188,16 +189,16 @@ citation("conjointTools")
#>
#> To cite conjointTools in publications use:
#>
#> John Paul Helveston. conjointTools: Tools for designing conjoint
#> survey experiments. (2020)
#> John Paul Helveston, Martin Lukac, Alberto Stefanelli (2020).
#> conjointTools: Tools For Designing Conjoint Survey Experiments.
#>
#> A BibTeX entry for LaTeX users is
#>
#> @Manual{,
#> title = {conjointTools: Tools for designing conjoint survey experiments.},
#> author = {John Paul Helveston},
#> title = {conjointTools: Tools For Designing Conjoint Survey Experiments},
#> author = {John Paul Helveston and Martin Lukac and Alberto Stefanelli},
#> year = {2020},
#> note = {R package version 0.0.1},
#> note = {R package version 0.0.2},
#> url = {https://jhelvy.github.io/conjointTools/},
#> }
```
2 changes: 1 addition & 1 deletion inst/CITATION
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ citEntry(
title = "conjointTools: Tools For Designing Conjoint Survey Experiments",
author = c("John Paul Helveston", "Martin Lukac", "Alberto Stefanelli"),
year = "2020",
note = "R package version 0.0.1",
note = "R package version 0.0.2",
url = "https://jhelvy.github.io/conjointTools/",
textVersion = "John Paul Helveston, Martin Lukac, Alberto Stefanelli (2020). conjointTools: Tools For Designing Conjoint Survey Experiments."
)
99 changes: 99 additions & 0 deletions inst/example/interactions.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
library(conjointTools)
library(ggplot2)

# Compute and compare standard errors for different sample sizes

# Example 1 -------------------------------------------------------------------

# A simple conjoint experiment about apples
# The price attribute is continuous.
# ALL interactions between each attribute are estimated
# Full factorial design

# Make the design of experiment
doe <- makeDoe(
levels = c(3, 3, 3),
varNames = c("price", "type", "freshness"),
type = "full"
)

# Make the survey
survey <- makeSurvey(
doe = doe, # Design of experiment
nResp = 1000, # Total number of respondents (upper bound)
nAltsPerQ = 3, # Number of alternatives per question
nQPerResp = 6 # Number of questions per respondent
)

# Compute sample sizes
results <- sampleSizer(
survey = survey,
parNames = c('price', 'type', 'freshness'),
parTypes = c('c', 'd', 'd'),
interactions = TRUE, # Add interactions between each attribute
nbreaks = 10
)

# Preview results
head(results)

# Plot results
library(ggplot2)
results$int <- ifelse(grepl("\\*", results$coef), TRUE, FALSE)
ggplot(results) +
geom_point(aes(x = size, y = se, color = coef),
fill = "white", pch = 21) +
facet_wrap(vars(int)) +
scale_y_continuous(limits = c(0, NA)) +
labs(x = 'Number of observations',
y = 'Standard Error',
color = "Variable") +
theme_bw()

# Example 2 -------------------------------------------------------------------

# A simple conjoint experiment about apples
# The price attribute is continuous.
# ALL interactions between each attribute are estimated
# D-efficient partial factorial design

# Make the design of experiment
doe <- makeDoe(
levels = c(3, 3, 3),
varNames = c("price", "type", "freshness"),
type = "D",
nTrials = 15
)

# Make the survey
survey <- makeSurvey(
doe = doe, # Design of experiment
nResp = 1000, # Total number of respondents (upper bound)
nAltsPerQ = 3, # Number of alternatives per question
nQPerResp = 6 # Number of questions per respondent
)

# Compute sample sizes
results <- sampleSizer(
survey = survey,
parNames = c('price', 'type', 'freshness'),
parTypes = c('c', 'd', 'd'),
interactions = TRUE, # Add interactions between each attribute
nbreaks = 10
)

# Preview results
head(results)

# Plot results
library(ggplot2)
results$int <- ifelse(grepl("\\*", results$coef), TRUE, FALSE)
ggplot(results) +
geom_point(aes(x = size, y = se, color = coef),
fill = "white", pch = 21) +
facet_wrap(vars(int)) +
scale_y_continuous(limits = c(0, NA)) +
labs(x = 'Number of observations',
y = 'Standard Error',
color = "Variable") +
theme_bw()
Loading

0 comments on commit a5c8e63

Please sign in to comment.