Skip to content

Commit 73f79fe

Browse files
committed
mulitple regression in 2nd level batch
1 parent e95166f commit 73f79fe

File tree

3 files changed

+129
-31
lines changed

3 files changed

+129
-31
lines changed

Second_level_analysis_template_scripts/b_copy_to_local_scripts_dir_and_modify/a2_set_default_options.m

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
% --------------------------------------------------------------------
1515
dorobust = true; % robust statistics [true, false] -- default true
1616
myscaling = 'raw'; % 'raw' or 'scaled'
17+
design_matrix_type = 'custom'; % 'group' or 'custom'
18+
% Group: use DAT.BETWEENPERSON.group or DAT.BETWEENPERSON.contrasts{c}.group;
19+
% Custom: use all columns of table object DAT.BETWEENPERSON.contrasts{c};
1720

1821
% prep_3b_run_SVMs_on_contrasts_and_save options
1922
% --------------------------------------------------------------------

Second_level_analysis_template_scripts/core_scripts_to_run_without_modifying/d9_nps_correlations_with_global_signal.m

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,28 @@
99

1010
clear r p
1111

12+
% corr performance changed from Matlab 2017b to 2018a. Could be bug in
13+
% 2018a.
14+
use_alt_method = false;
15+
myversion = ver('Matlab');
16+
if datenum(myversion.Date) > datenum('01-Jan-2018')
17+
use_alt_method = true;
18+
end
19+
20+
1221
for i = 1:k
1322

14-
[r(i, :), p(i, :)] = corr(DAT.npscontrasts{i}, DAT.gray_white_csf_contrasts{i});
23+
if use_alt_method
24+
25+
[tmpr, tmpp] = corr([DAT.npscontrasts{i} DAT.gray_white_csf_contrasts{i}]);
26+
r(i, :) = tmpr(1, 2:end);
27+
p(i, :) = tmpp(1, 2:end);
28+
29+
else
30+
31+
[r(i, :), p(i, :)] = corr(DAT.npscontrasts{i}, DAT.gray_white_csf_contrasts{i});
32+
33+
end
1534

1635
end
1736

Second_level_analysis_template_scripts/core_scripts_to_run_without_modifying/prep_3a_run_second_level_regression_and_save.m

Lines changed: 106 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,29 @@
1-
% THIS SCRIPT RUNS BETWEEN-PERSON CONTRASTS using second-level regression
1+
% THIS SCRIPT RUNS BETWEEN-PERSON (2nd-level) Regression analyses
2+
% for each within-person CONTRAST registered in the analysis
3+
%
4+
% - To specify analysis options, run a2_set_default_options
5+
% - prep_3a_run_second_level_regression_and_save runs regressions and saves
6+
% results in a standard location and format
7+
% - To get results reports, see c2a_second_level_regression
28
%
3-
% FOR NOW: Uses "group" variable.
4-
% FUTURE: Extend this to arbitrary covariates (> 1 cov), which have to be
5-
% entered in DAT structure in some standardize place.
9+
% Analysis options include:
10+
% - dorobust : robust regression or OLS (true/false)
11+
% - myscaling: 'raw' or 'scaled' (image scaling done in prep_2_... data load)
12+
% - design_matrix_type: 'group' or 'custom'
13+
% Group: use DAT.BETWEENPERSON.group or DAT.BETWEENPERSON.contrasts{c}.group;
14+
% Custom: use all columns of table object DAT.BETWEENPERSON.contrasts{c};
615
%
7-
% Assuming that groups are concatenated into contrast image lists.
8-
% Requires DAT.BETWEENPERSON.group field specifying group membership for
16+
% 'group' option
17+
% Assuming that groups are concatenated in contrast image lists, and
18+
% regressor values of 1 or -1 will specify the group identity for each
19+
% image. Requires DAT.BETWEENPERSON.group field specifying group membership for
920
% each image.
21+
%
22+
% 'custom' option:
23+
% Can enter a multi-column design matrix for each contrast
24+
% Design matrix can be different for each contrast
25+
%
26+
% To set up group and custom variables, see prep_1b_prep_behavioral_data
1027

1128
% --------------------------------------------------------------------
1229

@@ -21,10 +38,10 @@
2138
% (e.g., not specified in an older/incomplete copy of a2_set_default_options)
2239

2340
% Now set in a2_set_default_options
24-
options_needed = {'dorobust', 'myscaling'}; % Options we are looking for. Set in a2_set_default_options
41+
options_needed = {'dorobust', 'myscaling', 'design_matrix_type'}; % Options we are looking for. Set in a2_set_default_options
2542
options_exist = cellfun(@exist, options_needed);
2643

27-
option_default_values = {false 'raw'}; % defaults if we cannot find info in a2_set_default_options at all
44+
option_default_values = {false, 'raw', 'group'}; % defaults if we cannot find info in a2_set_default_options at all
2845

2946
plugin_get_options_for_analysis_script
3047

@@ -65,15 +82,34 @@
6582

6683
for c = 1:kc
6784

85+
% Get design matrix for this contrast
86+
% --------------------------------------------------------------------
87+
6888
mygroupnamefield = 'contrasts'; % 'conditions' or 'contrasts'
69-
[group, groupnames, groupcolors] = plugin_get_group_names_colors(DAT, mygroupnamefield, c);
70-
outcome_value = group;
7189

72-
if isempty(group)
73-
fprintf('Group not defined for contrast %s. Skipping.\n', DAT.contrastnames{c});
74-
continue
90+
switch design_matrix_type
91+
case 'custom'
92+
93+
% Define design matrix X "design_matrix"
94+
% Use custom matrix for each condition/contrast
95+
table_obj = DAT.BETWEENPERSON.(mygroupnamefield){c};
96+
groupnames = table_obj.Properties.VariableNames;
97+
X = table2array(table_obj);
98+
99+
case 'group'
100+
101+
% Use 'groups' single regressor
102+
[group, groupnames, groupcolors] = plugin_get_group_names_colors(DAT, mygroupnamefield, c);
103+
X = group;
104+
105+
if isempty(group)
106+
fprintf('Group not defined for contrast %s. Skipping.\n', DAT.contrastnames{c});
107+
continue
108+
end
109+
110+
otherwise error('Incorrect option specified for design_matrix_type');
75111
end
76-
112+
77113
printstr(DAT.contrastnames{c});
78114
printstr(dashes)
79115

@@ -100,26 +136,58 @@
100136

101137
% a. Format and attach outcomes: 1, -1 group variable FOR NOW
102138
% --------------------------------------------------------------------
103-
104-
% Confirm outcome_value is 1, -1, or mean-centered
105-
% *****add this*****
106139

107-
% Check multilinearity, variance in all regressors; error for bad
108-
% design matrix
109-
% *****add this*****
140+
% Confirm design_matrix is 1, -1, or mean-centered
141+
meancentered = ~(abs(mean(X)) > 1000 * eps);
142+
effectscoded = all(X == 1 | X == -1 | X == 0, 1);
143+
isconstant = all(X == mean(X, 1), 1);
144+
vifs = getvif(X);
110145

111-
cat_obj.X = outcome_value;
146+
if any(isconstant)
147+
disp('An intercept appears to be added manually. Do not include an intercept - it will be added automatically.');
148+
disp('Skipping this contrast.')
149+
continue
150+
end
151+
152+
% Report
153+
design_table = table;
154+
design_table.Mean = mean(X)';
155+
design_table.Var = var(X)';
156+
design_table.EffectsCode = effectscoded';
157+
design_table.VIF = vifs';
158+
design_table.Properties.RowNames = groupnames';
159+
disp(design_table)
160+
disp(' ');
112161

113-
% Skip if necessary
114-
% --------------------------------------------------------------------
162+
if any(~meancentered & ~effectscoded)
163+
disp('Warning: some columns are not mean-centered or effects coded. \nIntercept may not be interpretable.\n');
164+
fprintf('Columns: ')
165+
fprintf('%d ', find(~meancentered & ~effectscoded));
166+
fprintf('\n');
167+
else
168+
disp('Checked OK: All columns mean-centered or are effects-coded [1 -1 0]');
169+
end
115170

116-
if all(cat_obj.X > 0) || all(cat_obj.X < 0)
117-
% Only positive or negative weights - nothing to compare
118-
119-
printhdr(' Only positive or negative regressor values - bad design');
120-
121-
continue
171+
172+
if any(vifs) > 2
173+
disp('Some regressors have high variance inflation factors: Parameters might be poorly estimated or uninterpretable.');
174+
else
175+
disp('Checked OK: VIFs for all columns are < 2');
122176
end
177+
178+
179+
cat_obj.X = X;
180+
181+
% Skip if necessary
182+
% --------------------------------------------------------------------
183+
%
184+
% if all(cat_obj.X > 0) || all(cat_obj.X < 0)
185+
% % Only positive or negative weights - nothing to compare
186+
%
187+
% printhdr(' Only positive or negative regressor values - bad design');
188+
%
189+
% continue
190+
% end
123191

124192
% Run voxel-wise regression model
125193
% --------------------------------------------------------------------
@@ -134,7 +202,9 @@
134202
% out.t has t maps for all regressors, intercept is last
135203
regression_stats = regress(cat_obj, .05, 'unc', robuststring, 'analysis_name', DAT.contrastnames{c}, 'variable_names', {'Group'});
136204

205+
137206
% Make sure variable types are right data formats
207+
regression_stats.design_table = design_table;
138208
regression_stats.t = enforce_variable_types(regression_stats.t);
139209
regression_stats.b = enforce_variable_types(regression_stats.b);
140210
regression_stats.df = enforce_variable_types(regression_stats.df);
@@ -146,7 +216,12 @@
146216

147217
% add names for analyses and variables:
148218
regression_stats.analysis_name = DAT.contrastnames{c};
149-
regression_stats.variable_names = {'Group' 'Intercept'}
219+
regression_stats.variable_names = [groupnames {'Intercept'}];
220+
221+
% prints output automatically - name axis
222+
for kk = 1:length(regression_stats.variable_names)
223+
spm_orthviews_name_axis(regression_stats.variable_names{kk}, kk);
224+
end
150225

151226
% Save stats objects for results later
152227
% --------------------------------------------------------------------
@@ -164,6 +239,7 @@
164239

165240
save(savefilenamedata, 'regression_stats_results', '-v7.3');
166241
printhdr('Saved regression_stats_results for contrasts');
242+
fprintf('Filename: %s\n', savefilenamedata);
167243

168244

169245

0 commit comments

Comments
 (0)