Created
August 5, 2014 05:21
-
-
Save onesandzeroes/25fe61eb535a3acd02fd to your computer and use it in GitHub Desktop.
Randomized block assignment in Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import division | |
import random | |
import pprint | |
def assign_blocks(total_n, block_sizes): | |
block_size_list = [] | |
current_n = 0 | |
while current_n < total_n: | |
max_size = total_n - current_n | |
possible_sizes = [s for s in block_sizes if s <= max_size] | |
current_size = random.choice(possible_sizes) | |
block_size_list.append(current_size) | |
current_n += current_size | |
print("Block sizes:") | |
pprint.pprint(block_size_list) | |
final_assignments = [] | |
for size in block_size_list: | |
current_treatments = create_block(size) | |
final_assignments.extend(current_treatments) | |
return final_assignments | |
def weighted_choice(choices): | |
total = sum(w for c, w in choices) | |
r = random.uniform(0, total) | |
upto = 0 | |
for c, w in choices: | |
if upto + w > r: | |
return c | |
upto += w | |
assert False, "Shouldn't get here" | |
def create_block(size): | |
N_A = size / 2 | |
N_B = size / 2 | |
n_a = 0 | |
n_b = 0 | |
treatments = [] | |
while len(treatments) < size: | |
p_a = (N_A - n_a) / (N_A + N_B - n_a - n_b) | |
p_b = (N_B - n_b) / (N_A + N_B - n_a - n_b) | |
current_treatment = weighted_choice([('A', p_a), ('B', p_b)]) | |
treatments.append(current_treatment) | |
if current_treatment == 'A': | |
n_a += 1 | |
if current_treatment == 'B': | |
n_b += 1 | |
return treatments |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment