Test for Individual Differences

Lesson

Elijah Galvan

September 1, 2023

12 min read

Goal During this Stage

We want to explicitly test whether or not people are different from each other, or if our findings indicate a tendency that is true of all people in the same way.

How to Achieve this Goal

Embodying No Individual Differences

We’ve already identified the best model and now we want to see if the instance that we proved was best - where we estimated Free Parameters for each Subjects - was justified in its complexity. Even if our best model captures ‘individual differences’ - i.e. multiple potential strategies - it does not necessarily mean that Subjects are different. Instead it indicates that this multinorm model is able to capture behavior that is not explained by any simplification of it. Testing for individual differences invovles training an instance of our model over data where we do not differentiate between Subjects and we then compare this model’s performance to a

result = fmincon(obj_function,x0 = initial_params, A = NULL, b = NULL, Aeq = NULL, beq = NULL,
                 lb = lower_bounds, ub = upper_bounds,
                 df = trialData)

trialData$PredictedNID = vector('numeric', length(trialData$SubjectID))
for (i in 1:length(trialData$IV)){
    Utility = vector('numeric', length(Choices))
    for (j in 1:length(Choices)){
        Utility[j] = utility(parameter1 = results$par[1],
                             parameter2 = results$par[2],
                             construct1 = construct1(trialData$IV[k], trialData$Constant[k], Choices[n]),
                             construct2 = construct2(trialData$IV[k], trialData$Constant[k], Choices[n]),
                             construct3 = construct3(trialData$IV[k], trialData$Constant[k], Choices[n]))
    }
    trialData$PredictedNID[i] = Choices[which(Utility == max(Utility))]
}

subjectData$SS_NID = vector('numeric', length(subjectDatasubjectData$SubjectID))
for (i in 1:length(subjectData$SubjectID)){
    trials = which(subjectData$SubjectID[i] == trialData$SubjectID)
    subjectData$SS_NID[i] = sum((trialData$Decision[trials] - trialData$PredictedNID[trials])**2)
}

# number of parameter divided by the number of people (i.e. number of parameters for each person)
subjectData$AIC_NID = length(trialList$IV) * log(subjectData$SS_NID/length(trialList$IV)) + 2 * (2/length(subjectData$SubjectID))

t.test(subjectData$AIC_NID, subjectData$model_AIC, paired = T)
options = optimoptions('fmincon', 'Algorithm', 'interior-point');
result = fmincon(@(params) obj_function(params, trialData, 'OLS'), initial_params, [], [], [], [], lower_bounds, upper_bounds, [], options);

trialData.PredictedNID = zeros(length(trialData.SubjectID), 1);
for i = 1:length(trialData.IV)
    Utility = zeros(length(Choices), 1);
    for j = 1:length(Choices)
        Utility(j) = utility(result(1), result(2), ...
                             construct1(trialData.IV(i), trialData.Constant(i), Choices(j)), ...
                             construct2(trialData.IV(i), trialData.Constant(i), Choices(j)), ...
                             construct3(trialData.IV(i), trialData.Constant(i), Choices(j)));
    end
    [~, idx] = max(Utility);
    trialData.PredictedNID(i) = Choices(idx);
end

subjectData.SS_NID = zeros(length(subjectData.SubjectID), 1);
for i = 1:length(subjectData.SubjectID)
    trials = find(subjectData.SubjectID(i) == trialData.SubjectID);
    subjectData.SS_NID(i) = sum((trialData.Decision(trials) - trialData.PredictedNID(trials)).^2);
end

subjectData.AIC_NID = length(trialList.IV) * log(subjectData.SS_NID / length(trialList.IV)) + 2 * (2 / length(subjectData.SubjectID));

ttest(subjectData.AIC_NID, subjectData.model_AIC, 'paired');
result = minimize(lambda params: obj_function(params, trialData, 'OLS'), initial_params, bounds=list(zip(lower_bounds, upper_bounds)))

trialData['PredictedNID'] = np.zeros(len(trialData['SubjectID']))
for i in range(len(trialData['IV'])):
    Utility = np.zeros(len(Choices))
    for j in range(len(Choices)):
        Utility[j] = utility(result.x[0], result.x[1],
                             construct1(trialData['IV'].iloc[i], trialData['Constant'].iloc[i], Choices[j]),
                             construct2(trialData['IV'].iloc[i], trialData['Constant'].iloc[i], Choices[j]),
                             construct3(trialData['IV'].iloc[i], trialData['Constant'].iloc[i], Choices[j]))
    trialData['PredictedNID'].iloc[i] = Choices[np.argmax(Utility)]

subjectData['SS_NID'] = np.zeros(len(subjectData['SubjectID']))
for i in range(len(subjectData['SubjectID'])):
    trials = np.where(subjectData['SubjectID'].iloc[i] == trialData['SubjectID'])[0]
    subjectData['SS_NID'].iloc[i] = np.sum((trialData['Decision'].iloc[trials] - trialData['PredictedNID'].iloc[trials]) ** 2)

subjectData['AIC_NID'] = len(trialList['IV']) * np.log(subjectData['SS_NID'] / len(trialList['IV'])) + 2 * (2 / len(subjectData['SubjectID']))

ttest_rel(subjectData['AIC_NID'], subjectData['model_AIC'])

Tutorials

Tutorial 1 - van Baar, Chang, & Sanfey, 2019

Embodying No Individual Differences
result = fmincon(obj_function,x0 = initial_params, A = NULL, b = NULL, Aeq = NULL, beq = NULL,
    lb = lower_bounds, ub = upper_bounds,
    df = trialData)

trialData$PredictedNID = vector('numeric', length(trialData$Subject))
for (i in 1:length(trialData$Subject)){
    if (trialData$Investment[i] > 10) {
        Choices = seq(0, (trialData$Investment[i] * trialData$Multiplier[i]), round((trialData$Investment[i]*trialData$Multiplier[i])/10))
    } else {
        Choices = seq(0, (trialData$Investment[i] * trialData$Multiplier[i]), 1)
    }
    Utility = vector('numeric', length(Choices))
    for (n in 1:length(Choices)){
        Utility[n] = utility(theta = result$par[1],
                            phi = result$par[2],
                            payout = payout_maximization(trialData$Investment[i], trialData$Multiplier[i], Choices[n]),
                            guilt = guilt(trialData$Investment[i], believed_multiplier = 4, Choices[n], trialData$Multiplier[i]),
                            inequity = inequity(trialData$Investment[i], trialData$Multiplier[i], Choices[n], endowment = 10))
    }
trialData$PredictedNID[i] = Choices[which(Utility == max(Utility))]
}
subjectData$SS_NID = vector('numeric', length(subjectData$SubjectID))

for (i in 1:length(subjectData$SubjectID)){
    trials = which(subjectData$SubjectID[i] == trialData$Subject)
    subjectData$SS_NID[i] = sum((as.numeric(trialData$Returned[trials]) - trialData$PredictedNID[trials])**2)
}

# number of parameter divided by the number of people (i.e. number of parameters for each person)
subjectData$AIC_NID = length(df$Investment) * log(subjectData$SS_NID/length(df$Investment)) + 2 * (2/length(subjectData$SubjectID))

t.test(subjectData$modelAIC, subjectData$AIC_NID, paired = T)

summary(lm(data = trialData, as.numeric(Returned) ~ PredictedNID))

aic_id = c(mean(subjectData$modelAIC), mean(subjectData$AIC_NID))

qplot(y = aic_id,
      x = as.factor(c('Individual Differences', 'No Individual Differences')),
      fill = as.factor(c('Individual Differences', 'No Individual Differences')),
      color = '',
      geom = 'col') +
    labs(x = 'Model', y = 'AIC', fill = NULL) + lims(y = c(-5, 155)) +
    theme_minimal() +
    geom_signif(comparisons = list(c('Individual Differences', 'No Individual Differences')), y_position = 135, textsize = 0, tip_length = 0.15)+
    annotate("text", x = 1.5, y = 135,
            label = "p = 0.18", vjust = -1, size = 4) +
    scale_fill_manual(values = c(rgb(218, 165, 32, maxColorValue = 255), rgb(132.5, 132.5, 132.5, maxColorValue = 255))) +
    scale_color_manual(values = c(rgb(0, 0, 0, maxColorValue = 255)))
result = fmincon(@(params) obj_function(params, trialData), initial_params, [], [], [], [], lower_bounds, upper_bounds);

trialData.PredictedNID = NaN(1, length(trialData.Subject));
for i = 1:length(trialData.Subject)
    if trialData.Investment(i) > 10
        Choices = 0:round((trialData.Investment(i) * trialData.Multiplier(i))/10):(trialData.Investment(i) * trialData.Multiplier(i));
    else
        Choices = 0:1:(trialData.Investment(i) * trialData.Multiplier(i));
    end

    Utility = NaN(1, length(Choices));
    for n = 1:length(Choices)
        Utility(n) = utility(result(1), result(2), ...
            payout_maximization(trialData.Investment(i), trialData.Multiplier(i), Choices(n)), ...
            guilt(trialData.Investment(i), 4, Choices(n), trialData.Multiplier(i)), ...
            inequity(trialData.Investment(i), trialData.Multiplier(i), Choices(n), 10));
    end

    [~, maxIndex] = max(Utility);
    trialData.PredictedNID(i) = Choices(maxIndex);
end

subjectData.SS_NID = NaN(1, length(subjectData.SubjectID));

for i = 1:length(subjectData.SubjectID)
    trials = find(subjectData.SubjectID(i) == trialData.Subject);
    subjectData.SS_NID(i) = sum((trialData.Returned(trials) - trialData.PredictedNID(trials)).^2);
end

subjectData.AIC_NID = length(df.Investment) * log(subjectData.SS_NID/length(df.Investment)) + 2 * (2/length(subjectData.SubjectID));

ttest(subjectData.modelAIC, subjectData.AIC_NID);

lm_result = fitlm(trialData, 'Returned ~ PredictedNID');
disp(lm_result);

aic_id = [mean(subjectData.modelAIC), mean(subjectData.AIC_NID)];

figure;
bar(categorical({'Individual Differences', 'No Individual Differences'}), aic_id, 'FaceColor', [0.85 0.85 0.85]);
ylabel('AIC');
ylim([-5 155]);
hold on;
sigstar({'Individual Differences', 'No Individual Differences'}, [0.15, 135, 1.5, 135], [0, 0, 0]);
text(1.5, 135, 'p = 0.18', 'VerticalAlignment', 'top', 'HorizontalAlignment', 'center', 'FontSize', 10);
hold off;
result = minimize(lambda params: obj_function(params, trialData), initial_params, bounds=list(zip(lower_bounds, upper_bounds)))

trialData['PredictedNID'] = np.nan
for i in range(1, len(trialData['Subject']) + 1):
    if trialData['Investment'].iloc[i - 1] > 10:
        Choices = np.arange(0, (trialData['Investment'].iloc[i - 1] * trialData['Multiplier'].iloc[i - 1]),
                            round((trialData['Investment'].iloc[i - 1] * trialData['Multiplier'].iloc[i - 1])/10))
    else:
        Choices = np.arange(0, (trialData['Investment'].iloc[i - 1] * trialData['Multiplier'].iloc[i - 1]), 1)

    Utility = np.zeros(len(Choices))
    for n in range(len(Choices)):
        Utility[n] = utility(result.x[0], result.x[1],
                            payout_maximization(trialData['Investment'].iloc[i - 1], trialData['Multiplier'].iloc[i - 1], Choices[n]),
                            guilt(trialData['Investment'].iloc[i - 1], 4, Choices[n], trialData['Multiplier'].iloc[i - 1]),
                            inequity(trialData['Investment'].iloc[i - 1], trialData['Multiplier'].iloc[i - 1], Choices[n], 10))

    correct_choice = Choices[np.argmax(Utility)]
    trialData.at[i - 1, 'PredictedNID'] = correct_choice

subjectData['SS_NID'] = np.nan

for i in range(1, len(subjectData['SubjectID']) + 1):
    trials = trialData[trialData['Subject'] == subjectData['SubjectID'].iloc[i - 1]]
    subjectData.at[i - 1, 'SS_NID'] = np.sum((trials['Returned'].to_numpy() - trials['PredictedNID'].to_numpy())**2)

subjectData['AIC_NID'] = len(df['Investment']) * np.log(subjectData['SS_NID']/len(df['Investment'])) + 2 * (2/len(subjectData['SubjectID']))

ttest_rel(subjectData['modelAIC'], subjectData['AIC_NID'])

lm_result = sm.OLS(trialData['Returned'], sm.add_constant(trialData['PredictedNID'])).fit()
print(lm_result.summary())

aic_id = [np.mean(subjectData['modelAIC']), np.mean(subjectData['AIC_NID'])]

plt.bar(['Individual Differences', 'No Individual Differences'], aic_id, color=[0.85, 0.85, 0.85])
plt.ylabel('AIC')
plt.ylim([-5, 155])
plt.xticks(rotation=45, ha='right')
plt.text(1.5, 135, 'p = 0.18', va='bottom', ha='center', fontsize=10)
plt.show()

Tutorial 2 - Galvan & Sanfey, 2024

Embodying No Individual Differences
trialData$PredictedNID = vector('numeric', length(trialData$SubjectID))

for (k in 1:length(conditions)){

    z = which(trialData$condition == conditions[j])
    df = trialData[z, c(6, 12:20, 2)]

    result = fmincon(obj_function,x0 = initial_params, A = NULL, b = NULL, Aeq = NULL, beq = NULL,
                    lb = lower_bounds, ub = upper_bounds,
                    df = df)

    for (i in 1:length(df)){
        Utility = vector('numeric', length(Choices))
        for (n in 1:length(Choices)){
            Utility[n] = utility(theta = result$par[1],
                                 phi = result$par[2],
                                 Equity = equity(new_value(df[i, 1:10], choices[n]), df[i, 1:10], choices[n]),
                                 Equality = equality(new_value(df[i, 1:10], choices[n]), df[i, 1:10], choices[n]),
                                 Payout = payout(new_value(df[i, 1], choices[n]), df[i, 1], choices[n]))
        }
        trialData$PredictedNID[z[i]] = Choices[which(Utility == max(Utility))]
    }
}

subjectData$SSNIDMerit = vector('numeric', length(subjectDatasubjectData$SubjectID))
subjectData$SSNIDEntitlement = vector('numeric', length(subjectDatasubjectData$SubjectID))
subjectData$SSNIDCorruption = vector('numeric', length(subjectDatasubjectData$SubjectID))
subjectData$SSNIDLuck = vector('numeric', length(subjectDatasubjectData$SubjectID))

for (i in 1:length(subjectData$SubjectID)){
    trialsMerit = which(subjectData$SubjectID[i] == trialData$SubjectID && 'merit' == trialData$Condition)
    trialsEntitlement = which(subjectData$SubjectID[i] == trialData$SubjectID && 'entitlement' == trialData$Condition)
    trialsCorruption = which(subjectData$SubjectID[i] == trialData$SubjectID && 'corruption' == trialData$Condition)
    trialsLuck = which(subjectData$SubjectID[i] == trialData$SubjectID && 'luck' == trialData$Condition)

    subjectData$SSNIDMerit[i] = sum((trialData$observedTaxRate[trialsMerit] - trialData$PredictedNID[trialsMerit])**2)
    subjectData$SSNIDEntitlement[i] = sum((trialData$observedTaxRate[trialsEntitlement] - trialData$PredictedNID[trialsEntitlement])**2)
    subjectData$SSNIDCorruption[i] = sum((trialData$observedTaxRate[trialsCorruption] - trialData$PredictedNID[trialsCorruption])**2)
    subjectData$SSNIDLuck[i] = sum((trialData$observedTaxRate[trialsLuck] - trialData$PredictedNID[trialsLuck])**2)
}

subjectData$AICNIDMerit = length(trialsMerit) * log(subjectData$SSNIDMerit/length(trialsMerit)) + 2 * (2/length(subjectData$SubjectID))
subjectData$AICNIDEntitlement = length(trialsEntitlement) * log(subjectData$SSNIDEntitlement/length(trialsEntitlement)) + 2 * (2/length(subjectData$SubjectID))
subjectData$AICNIDCorruption = length(trialsCorruption) * log(subjectData$SSNIDCorruption/length(trialsCorruption)) + 2 * (2/length(subjectData$SubjectID))
subjectData$AICNIDLuck = length(trialsLuck) * log(subjectData$SSNIDLuck/length(trialsLuck)) + 2 * (2/length(subjectData$SubjectID))

t.test(subjectData$AICMerit, subjectData$AICNIDMerit, paired = T, alternative = 'less', conf.int = (1 - alpha))
t.test(subjectData$AICEntitlement, subjectData$AICNIDEntitlement, paired = T, alternative = 'less', conf.int = (1 - alpha))
t.test(subjectData$AICCorruption, subjectData$AICNIDCorruption, paired = T, alternative = 'less', conf.int = (1 - alpha))
t.test(subjectData$AICLuck, subjectData$AICNIDLuck, paired = T, alternative = 'less', conf.int = (1 - alpha))
trialData.PredictedNID = zeros(1, length(trialData.SubjectID));

for j = 1:length(conditions)
    z = find(trialData.condition == conditions(j));
    df = trialData(z, [6, 12:20, 2]);

    result = fmincon(@(params) obj_function(params, df), initial_params, [], [], [], [], lower_bounds, upper_bounds);

    for i = 1:length(df)
        Utility = zeros(1, length(Choices));
        for n = 1:length(Choices)
            Utility(n) = utility(result(1), result(2), ...
                equity(new_value(df(i, 1:10), Choices(n)), df(i, 1:10), Choices(n)), ...
                equality(new_value(df(i, 1:10), Choices(n)), df(i, 1:10), Choices(n)), ...
                payout(new_value(df(i, 1), Choices(n)), df(i, 1), Choices(n)));
        end
        trialData.PredictedNID(z(i)) = Choices(Utility == max(Utility));
    end
end

subjectData.SSNIDMerit = zeros(1, length(subjectData.SubjectID));
subjectData.SSNIDEntitlement = zeros(1, length(subjectData.SubjectID));
subjectData.SSNIDCorruption = zeros(1, length(subjectData.SubjectID));
subjectData.SSNIDLuck = zeros(1, length(subjectData.SubjectID));

for i = 1:length(subjectData.SubjectID)
    trialsMerit = find(subjectData.SubjectID(i) == trialData.SubjectID & strcmp('merit', trialData.Condition));
    trialsEntitlement = find(subjectData.SubjectID(i) == trialData.SubjectID & strcmp('entitlement', trialData.Condition));
    trialsCorruption = find(subjectData.SubjectID(i) == trialData.SubjectID & strcmp('corruption', trialData.Condition));
    trialsLuck = find(subjectData.SubjectID(i) == trialData.SubjectID & strcmp('luck', trialData.Condition));

    subjectData.SSNIDMerit(i) = sum((trialData.observedTaxRate(trialsMerit) - trialData.PredictedNID(trialsMerit)).^2);
    subjectData.SSNIDEntitlement(i) = sum((trialData.observedTaxRate(trialsEntitlement) - trialData.PredictedNID(trialsEntitlement)).^2);
    subjectData.SSNIDCorruption(i) = sum((trialData.observedTaxRate(trialsCorruption) - trialData.PredictedNID(trialsCorruption)).^2);
    subjectData.SSNIDLuck(i) = sum((trialData.observedTaxRate(trialsLuck) - trialData.PredictedNID(trialsLuck)).^2);
end

subjectData.AICNIDMerit = length(trialsMerit) * log(subjectData.SSNIDMerit/length(trialsMerit)) + 2 * (2/length(subjectData.SubjectID));
subjectData.AICNIDEntitlement = length(trialsEntitlement) * log(subjectData.SSNIDEntitlement/length(trialsEntitlement)) + 2 * (2/length(subjectData.SubjectID));
subjectData.AICNIDCorruption = length(trialsCorruption) * log(subjectData.SSNIDCorruption/length(trialsCorruption)) + 2 * (2/length(subjectData.SubjectID));
subjectData.AICNIDLuck = length(trialsLuck) * log(subjectData.SSNIDLuck/length(trialsLuck)) + 2 * (2/length(subjectData.SubjectID));

alpha = 0.05;

ttest(subjectData.AICMerit, subjectData.AICNIDMerit, 'Tail', 'left', 'Alpha', alpha);
ttest(subjectData.AICEntitlement, subjectData.AICNIDEntitlement, 'Tail', 'left', 'Alpha', alpha);
ttest(subjectData.AICCorruption, subjectData.AICNIDCorruption, 'Tail', 'left', 'Alpha', alpha);
ttest(subjectData.AICLuck, subjectData.AICNIDLuck, 'Tail', 'left', 'Alpha', alpha);
trialData['PredictedNID'] = np.zeros(len(trialData['SubjectID']))

for j in range(len(conditions)):
    z = np.where(trialData['condition'] == conditions[j])[0]
    df = trialData.iloc[z, [5, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1]]

    result = minimize(lambda params: obj_function(params, df), initial_params, bounds=list(zip(lower_bounds, upper_bounds)))

    for i in range(len(df)):
        Utility = np.zeros(len(Choices))
        for n in range(len(Choices)):
            Utility[n] = utility(result.x[0], result.x[1],
                                equity(new_value(df.iloc[i, 0:9], Choices[n]), df.iloc[i, 0:9], Choices[n]),
                                equality(new_value(df.iloc[i, 0:9], Choices[n]), df.iloc[i, 0:9], Choices[n]),
                                payout(new_value(df.iloc[i, 0], Choices[n]), df.iloc[i, 0], Choices[n]))
        trialData.at[z[i], 'PredictedNID'] = Choices[np.argmax(Utility)]

subjectData['SSNIDMerit'] = np.zeros(len(subjectData['SubjectID']))
subjectData['SSNIDEntitlement'] = np.zeros(len(subjectData['SubjectID']))
subjectData['SSNIDCorruption'] = np.zeros(len(subjectData['SubjectID']))
subjectData['SSNIDLuck'] = np.zeros(len(subjectData['SubjectID']))

for i in range(len(subjectData['SubjectID'])):
    trialsMerit = np.where((subjectData['SubjectID'][i] == trialData['SubjectID']) & (trialData['Condition'] == 'merit'))[0]
    trialsEntitlement = np.where((subjectData['SubjectID'][i] == trialData['SubjectID']) & (trialData['Condition'] == 'entitlement'))[0]
    trialsCorruption = np.where((subjectData['SubjectID'][i] == trialData['SubjectID']) & (trialData['Condition'] == 'corruption'))[0]
    trialsLuck = np.where((subjectData['SubjectID'][i] == trialData['SubjectID']) & (trialData['Condition'] == 'luck'))[0]

    subjectData.at[i, 'SSNIDMerit'] = np.sum((trialData['observedTaxRate'][trialsMerit] - trialData['PredictedNID'][trialsMerit])**2)
    subjectData.at[i, 'SSNIDEntitlement'] = np.sum((trialData['observedTaxRate'][trialsEntitlement] - trialData['PredictedNID'][trialsEntitlement])**2)
    subjectData.at[i, 'SSNIDCorruption'] = np.sum((trialData['observedTaxRate'][trialsCorruption] - trialData['PredictedNID'][trialsCorruption])**2)
    subjectData.at[i, 'SSNIDLuck'] = np.sum((trialData['observedTaxRate'][trialsLuck] - trialData['PredictedNID'][trialsLuck])**2)

subjectData['AICNIDMerit'] = len(trialsMerit) * np.log(subjectData['SSNIDMerit'] / len(trialsMerit)) + 2 * (2 / len(subjectData['SubjectID']))
subjectData['AICNIDEntitlement'] = len(trialsEntitlement) * np.log(subjectData['SSNIDEntitlement'] / len(trialsEntitlement)) + 2 * (2 / len(subjectData['SubjectID']))
subjectData['AICNIDCorruption'] = len(trialsCorruption) * np.log(subjectData['SSNIDCorruption'] / len(trialsCorruption)) + 2 * (2 / len(subjectData['SubjectID']))
subjectData['AICNIDLuck'] = len(trialsLuck) * np.log(subjectData['SSNIDLuck'] / len(trialsLuck)) + 2 * (2 / len(subjectData['SubjectID']))

alpha = 0.05

ttest_rel(subjectData['AICMerit'], subjectData['AICNIDMerit'], alternative='less', nan_policy='omit')
ttest_rel(subjectData['AICEntitlement'], subjectData['AICNIDEntitlement'], alternative='less', nan_policy='omit')
ttest_rel(subjectData['AICCorruption'], subjectData['AICNIDCorruption'], alternative='less', nan_policy='omit')
ttest_rel(subjectData['AICLuck'], subjectData['AICNIDLuck'], alternative='less', nan_policy='omit')

Tutorial 3 - Crockett et al., 2014

Embodying No Individual Differences
resultNID = fmincon(obj_function, x0 = initial_params, lb = lower_bounds, ub = upper_bounds, df = trialData, optimMethod = "OLS")
dfNID = generate_predictions(trialData, resultNID)
sum(dfNID$choseHarm == round(dfNID$ProbHarm))/nrow(dfNID)

altSubjectData$Deviance_NID = 0

for (i in 1:length(included_subjects)){
df = grab_data(included_subjects[i]); if (is.character(df)){next} else {trials = which(included_subjects[i] == dfNID$SubjectID)}
df = dfNID[trials, ]
altSubjectData$Deviance_NID[i] = -2*sum(df$choseHarm * log(df$ProbHarm) + (1 - df$choseHarm) * log(1 - df$ProbHarm))
}

altSubjectData$BIC_NID = as.numeric(altSubjectData$Deviance_NID) + log(152) * 6/(nrow(dfNID))

t.test(subjectData$BIC[-20], altSubjectData$BIC_NID[-20], paired = T)
which(modelBIC > sum(altSubjectData$BIC_NID))

Tutorial 4 - Li et al., 2022

Embodying No Individual Differences
resultNID = fmincon(of_ar, x0 = initial_params[c(1,3:6)], lb = lower_bounds[c(1,3:6)], ub = upper_bounds[c(1,3:6)], df = trialData[2:8], optimMethod = "MLE")
pars = c(resultNID$par[1], 0, resultNID$par[2:5])
trialData$Prob1_NID = generatePredictions(pars, trialData)
sum(trialData$Chose1 == round(trialData$Prob1_NID))/nrow(trialData)
altSubjectData$Deviance_NID = 0
for (i in 1:length(included_subjects)){
trials = which(included_subjects[i] == trialData$SubjectID)
df = trialData[trials, ]
altSubjectData$Deviance_NID[i] = -2*sum(df$Chose1 * log(df$Prob1_NID) + (1 - df$Chose1) * log(1 - df$Prob1_NID))
}

altSubjectData$BIC_NID = as.numeric(altSubjectData$Deviance_NID) + log(65) * 6/(length(included_subjects))

t.test(altSubjectData$BIC_M5, altSubjectData$BIC_NID, paired = T)
which(modelBIC > sum(altSubjectData$BIC_NID))