Last active
July 18, 2018 15:50
-
-
Save jamesdunham/5600636d0a350dd6293553d956ed8c4a to your computer and use it in GitHub Desktop.
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
library(testthat) | |
devtools::load_all() | |
names_to_levels = function(item_names, gt_names) { | |
vapply(item_names, function(item_name) { | |
sum(grepl(paste0('^', item_name, '_gt[0-9]+$'), gt_names)) | |
}, integer(1)) | |
} | |
test_that('names_to_levels recovers number of choices per item given item names', { | |
expect_equal(names_to_levels('abortion', 'abortion_gt1'), c('abortion' = 1)) | |
expect_equal(names_to_levels('abortion', c('abortion_gt1', 'abortion_gt2')), | |
c('abortion' = 2)) | |
}) | |
lookup_gt_names = function(item_name, gt_names) { | |
gt_names[grepl(paste0('^', item_name, '_gt[0-9]+$'), gt_names)] | |
} | |
test_that('given an item name, lookup_gt_names returns its _gt variable names', { | |
expect_equal(lookup_gt_names('abortion', c('abortion_gt1', 'foo')), | |
'abortion_gt1') | |
}) | |
add_item_weights = function(item_data, item_names) { | |
# Add a variable counting non-missing item responses | |
item_data[, c("n_item_responses") := list(rowSums(!is.na(.SD))), .SDcols = item_names] | |
n_levels = names_to_levels(item_names, names(item_data)) | |
# Iterate over the _gt variables | |
for (item_name in item_names) { | |
for (gt_item in lookup_gt_names(item_name, names(item_data))) { | |
# Create for each _gt variable a _gt_weight variable indicating the weight | |
# given the item response | |
item_data[, paste0(gt_item, '_weight') := 1 / | |
# Divide by number of item levels | |
n_levels[item_name] / | |
# Divide by number of non-missing item responses | |
n_item_responses] | |
item_data[, paste0(gt_item, '_weighted') := list(get(gt_item) * | |
get(paste0(gt_item, '_weight')))] | |
} | |
} | |
item_data[] | |
} | |
test_that('adding item weights works as expected with a single item', { | |
# Create minimal test data | |
item_data = data.table::data.table( | |
abortion = c(0, 0, 1, 1, 1, 1), | |
affirmative_action = c(2, 1, 0, 1, 1, 2)) | |
item_data[, abortion_gt1 := as.integer(abortion > 0)] | |
item_data[, affirmative_action_gt1 := as.integer(affirmative_action > 0)] | |
item_data[, affirmative_action_gt2 := as.integer(affirmative_action > 1)] | |
single_item = add_item_weights(item_data, item_names = 'abortion') | |
expect_true('abortion_gt1_weight' %in% names(single_item)) | |
expect_true('abortion_gt1_weighted' %in% names(single_item)) | |
expect_true('n_item_responses' %in% names(single_item)) | |
expect_equal(single_item$abortion_gt1_weighted, | |
single_item$abortion_gt1 * single_item$abortion_gt1_weight) | |
expect_equal(single_item$n_item_responses, rep(1, 6)) | |
expect_equal(single_item$abortion_gt1_weight, rep(1, 6)) | |
}) | |
test_that('adding item weights works as expected with multiple items', { | |
## Create minimal test data | |
item_data = data.table::data.table( | |
abortion = c(0, 0, 1, 1, 1, 1), | |
affirmative_action = c(2, 1, 0, 1, 1, 2)) | |
item_data[, abortion_gt1 := as.integer(abortion > 0)] | |
item_data[, affirmative_action_gt1 := as.integer(affirmative_action > 0)] | |
item_data[, affirmative_action_gt2 := as.integer(affirmative_action > 1)] | |
two_items = add_item_weights(item_data, item_names = c('abortion', | |
'affirmative_action')) | |
expect_true('abortion_gt1_weight' %in% names(two_items)) | |
expect_true('affirmative_action_gt1_weight' %in% names(two_items)) | |
expect_true('affirmative_action_gt2_weight' %in% names(two_items)) | |
expect_true('n_item_responses' %in% names(two_items)) | |
expect_equal(two_items$n_item_responses, rep(2, 6)) | |
expect_equal(two_items$abortion_gt1_weight, rep(0.5, 6)) | |
expect_equal(two_items$affirmative_action_gt1_weight, rep(0.25, 6)) | |
expect_equal(two_items$affirmative_action_gt2_weight, rep(0.25, 6)) | |
expect_equal(two_items$abortion_gt1_weighted, | |
two_items$abortion_gt1 * two_items$abortion_gt1_weight) | |
expect_equal(two_items$affirmative_action_gt1_weighted, | |
two_items$affirmative_action_gt1 * two_items$affirmative_action_gt1_weight) | |
expect_equal(two_items$affirmative_action_gt2_weighted, | |
two_items$affirmative_action_gt2 * two_items$affirmative_action_gt2_weight) | |
}) | |
test_that('adding item weights works as expected with missingness', { | |
## Create minimal test data | |
item_data = data.table::data.table( | |
abortion = c(NA, 0, 1, 1, 1, 1), | |
affirmative_action = c(2, 1, NA, 1, 1, 2)) | |
item_data[, abortion_gt1 := as.integer(abortion > 0)] | |
item_data[, affirmative_action_gt1 := as.integer(affirmative_action > 0)] | |
item_data[, affirmative_action_gt2 := as.integer(affirmative_action > 1)] | |
two_items = add_item_weights(item_data, item_names = c('abortion', | |
'affirmative_action')) | |
expect_true('abortion_gt1_weight' %in% names(two_items)) | |
expect_true('affirmative_action_gt1_weight' %in% names(two_items)) | |
expect_true('affirmative_action_gt2_weight' %in% names(two_items)) | |
expect_true('n_item_responses' %in% names(two_items)) | |
expect_equal(two_items$n_item_responses, c(1, 2, 1, 2, 2, 2)) | |
expect_equal(two_items$abortion_gt1_weight, c(1, .5, 1, .5, .5, .5)) | |
expect_equal(two_items$affirmative_action_gt1_weight, c(.5, .25, .5, rep(.25, 3))) | |
expect_equal(two_items$affirmative_action_gt2_weight, c(.5, .25, .5, rep(.25, 3))) | |
expect_equal(two_items$abortion_gt1_weighted, | |
two_items$abortion_gt1 * two_items$abortion_gt1_weight) | |
expect_equal(two_items$affirmative_action_gt1_weighted, | |
two_items$affirmative_action_gt1 * two_items$affirmative_action_gt1_weight) | |
expect_equal(two_items$affirmative_action_gt2_weighted, | |
two_items$affirmative_action_gt2 * two_items$affirmative_action_gt2_weight) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment