Skip to content

Instantly share code, notes, and snippets.

@scytacki
Forked from kjola8/survey-cleaner.gs
Last active February 8, 2017 17:54
Show Gist options
  • Save scytacki/63c941ba8b676d27a480e94dd728e786 to your computer and use it in GitHub Desktop.
Save scytacki/63c941ba8b676d27a480e94dd728e786 to your computer and use it in GitHub Desktop.
Google Spreadsheet script to convert survey answers to numbers.
/*
The goal is to identify each column for the type that is
and then convert the cells to numbers.
To identify it, we need to ignore the first few rows which will be headers.We could probably be safe and just skip the first
4 rows and start there.
*/
function getUnique_(values) {
var o = {}, a = [], i, e;
for (i = 0; e = values[i]; i++) {o[e] = 1};
for (e in o) {a.push (e)};
return a;
}
function lookupIndex_(choiceList, value) {
var foundIndex = -1;
value = value.toString();
if(value == ""){
return "";
}
if(value == "not answered"){
return [];
}
// If this is a multiple answer then just asume it is not answered for now
if(value.indexOf(", (") > 2){
return [];
}
choiceList.forEach(function (answers, index){
// answers will either be a string or an array
// so either "Strongly disagree" or ["Strongly disagree" , "Strongly Disagree"]
if(typeof(answers) == "string"){
if(answers == value){
foundIndex = index;
}
} else {
if(answers.indexOf(value) >= 0){
foundIndex = index;
}
}
});
return foundIndex;
}
function demographics_(value){
return lookupIndex_(["not answered", "boy", "girl"], value);
}
var ethnicity = ["not answered", "Non-Hispanic White or Euro-American", "Black, Afro-Caribbean, or African Amercan", "Latino or Hispanic American", "East Asian or Asian American", "South Asian or Indian American", "Middle Eastern or Arab American", "Native American or Alaskan Native", "Other", "I don’t want to respond"];
var environment = ["not answered", "urban area", "suburban area", "rural area"];
function demographicsQuestion0_(value){
return lookupIndex_(ethnicity, value);
}
function demographicsQuestion1_(value){
return lookupIndex_(environment, value);
}
function numericQuestion_(value){
if(value == ""){
return "";
}
if(value == "not answered"){
return "";
}
if(!isNaN(value)){
return value;
} else {
return -1;
}
}
var surveyQuestionChoices = [
["not answered", "(1)Disagree","(2)","(3)","(4)Agree"],
["not answered",
["Strongly disagree", "(1)Strongly disagree"],
["Disagree", "Disgree", "(2)Disagree", "disagree"],
["Neither agree nor disagree", "Neither agree or disagree", "Neither agree not disagree", "c. Neither agree nor disagree", "(3)Neither agree nor disagree"],
["Agree", "(4)Agree"],
["Strongly agree", "Strongly Agree", "(5)Strongly disagree"]],
["not answered", "a. No", "b. Yes", "c. Not sure"],
["not answered", "(1)Not important","(2)","(3)","(4)Very important"],
];
function surveyQuestion0_(value){
return lookupIndex_(surveyQuestionChoices[0], value);
}
function surveyQuestion1_(value){
return lookupIndex_(surveyQuestionChoices[1], value);
}
function surveyQuestion2_(value){
return lookupIndex_(surveyQuestionChoices[2], value);
}
function surveyQuestion3_(value){
return lookupIndex_(surveyQuestionChoices[3], value);
}
function correctIncorrectValue_(value){
value = value.toString();
if(value.indexOf("(wrong)") == 0){
return 0;
}
if(value == "not answered"){
return [];
}
if(value.indexOf("(correct)") == 0){
return 1;
}
if(value == ""){
return "";
}
return -1;
}
// This is specific to the Content Knowledge activity where
// true is the correct answer and false is incorrect
function trueFalseValue_(value){
value = value.toString();
if(value.indexOf("b. False") == 0){
return 0;
}
if(value == "not answered"){
return [];
}
if(value.indexOf("a. True") == 0){
return 1;
}
if(value == ""){
return "";
}
return -1;
}
function replaceCorrectIncorrect(){
replaceWithValueFunctions_([
correctIncorrectValue_,
trueFalseValue_
]);
}
function replaceSurveyAnswers(){
replaceWithValueFunctions_([
surveyQuestion0_,
surveyQuestion1_,
surveyQuestion2_,
surveyQuestion3_,
demographics_,
demographicsQuestion0_,
demographicsQuestion1_,
numericQuestion_
]);
}
function replaceWithValueFunctions_(valueFunctions){
Logger.log(SpreadsheetApp.getActive().getName());
var sheet = SpreadsheetApp.getActiveSheet();
// This represents ALL the data
var range = sheet.getDataRange();
var values = range.getValues();
var startingRow = 1;
var numRows = values.length
var numCols = values[0].length
// var numCols = 26;
for (var col = 0; col < numCols; col++) {
var allColValues = [];
for (var row = startingRow; row < numRows; row++) {
allColValues.push(values[row][col]);
}
var matchingValueFunction = null;
var allValuesMatch = true;
var firstNonMatchingValues = [];
for (var valueFunctionIndex = 0; valueFunctionIndex < valueFunctions.length; valueFunctionIndex++){
var valueFunction = valueFunctions[valueFunctionIndex];
allValuesMatch = true;
for (var row = 0; row < allColValues.length; row++){
colValue = allColValues[row];
if(valueFunction(colValue) != -1){
// matching value
} else {
allValuesMatch = false;
firstNonMatchingValues.push(colValue);
break;
}
}
if(allValuesMatch){
matchingValueFunction = valueFunction;
break;
}
}
Logger.log("Col: " + col +
" matches: " + valueFunctions.indexOf(matchingValueFunction) +
" firstNonMatchingValues: " + firstNonMatchingValues);
if(matchingValueFunction == null){
continue;
}
var updateRange = sheet.getRange(startingRow+1, col+1, numRows - startingRow, 1);
var updateValues = [];
// this will result in this [ [2], [1], [0] ]
allColValues.forEach(function(colValue){
var value = colValue.toString();
updateValues.push([ matchingValueFunction(colValue) ]);
});
updateRange.setValues(updateValues);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment