Because all inputs to declare_design() are functions, it’s easy for you to provide custom functions instead of using our defaults.

Custom Population

You can use a custom function to generate your population entirely on your own, too:

my_population_function <- function(N) {
  data.frame(u = rnorm(N))
}

my_population_custom <- declare_population(
  population_function = my_population_function, N = 100)

pop_custom <- my_population_custom()

head(pop_custom)
u
-0.35
0.61
0.74
0.48
0.33
-1.78

Custom Potential Outcomes

my_potential_outcomes_function <-
  function(data) {
    data$Y_Z_0 <- with(data, u)
    data$Y_Z_1 <- with(data, 0.25 + u)
    data
  }
my_potential_outcomes_custom <- declare_potential_outcomes(
  potential_outcomes_function = my_potential_outcomes_function
)

pop_pos_custom <- my_potential_outcomes_custom(pop_custom)

head(pop_pos_custom[, c("u", "Y_Z_0", "Y_Z_1")])
u Y_Z_0 Y_Z_1
-0.35 -0.35 -0.10
0.61 0.61 0.86
0.74 0.74 0.99
0.48 0.48 0.73
0.33 0.33 0.58
-1.78 -1.78 -1.53

Custom Sampling

Again, you can still use a custom sampling function easily. In this case, the requirement is simply that the function takes population data and returns sampled data. You can also include inclusion weights if you wish in the function (as the default function does).

my_sampling_function <- function(data) {
     data$S <- rbinom(n = nrow(data),
            size = 1,
            prob = 0.1)
     data[data$S == 1, ]
}

my_sampling_custom <- declare_sampling(
  sampling_function = my_sampling_function)

smp_custom <- my_sampling_custom(pop_pos)

nrow(smp_custom)

107

Custom Assignment

my_assignment_function <- function(data) {
  data$Z <- rbinom(n = nrow(data),
         size = 1,
         prob = 0.5)
  data
}
my_assignment_custom <- declare_assignment(
  assignment_function = my_assignment_function)

table(my_assignment_custom(pop_pos)$Z)
0 1
504 496

Custom Estimand

my_estimand_function <- function(data) {
  with(data, median(Y_Z_1 - Y_Z_0))
}
my_estimand_custom <- declare_estimand(
  estimand_function = my_estimand_function, label = medianTE)

my_estimand_custom(pop_pos)
estimand_label estimand
medianTE 0.82

Custom Estimator

my_estimator_function <- function(formula, data){
  data.frame(est = with(data, mean(Y)))
}

my_estimator_custom <- 
  declare_estimator(Y ~ Z, 
                    estimator_function = my_estimator_function, 
                    estimand = my_estimand)

my_estimator_custom(smp)
estimator_label est estimand_label
my_estimator 0.09 ATE