Applying a function across all columns of a table

5 views (last 30 days)
T = readtable('agree'); %%name of table
T.Q1(strcmpi(T.Q1,'Agree')) = {1}; %% change all results in column called Q1 to 1 if agree appears
T.Q1(strcmpi(T.Q1,'Strongly Agree')) = {1}; %% change all results in column called Q1 to 1 if strongly agree appears
T.Q1(strcmpi(T.Q1,'Disagree')) = {0}; %% change all results in column called Q1 to 0 if disagree appears
T.Q1(strcmpi(T.Q1,'Neither Agree Nor Disagree')) = {0};%% change all results in column called Q1 to 0 if neither agree nor disagree appears
T.Q1(strcmpi(T.Q1,'Strongly Disagree')) = {0}; %% change all results in column called Q1 to 0 if strongly disagree appears
T.Q1(strcmpi(T.Q1,"Don't know")) = {0} %% change all results in column called Q1 to 0 if Don't know appears
I have a table of 40 columns which has data from a survey based on a 5 point Likert scale. I want to change the results to binary results, where strongly agree and agree are represented by 1 and everything else is represented by 0. The code above achieves this, but I want to make it into a function which runs it for the whole table and doesnt require me to change the name of the column each time. Could anyone help?

Accepted Answer

Ive J
Ive J on 7 Dec 2020
Edited: Ive J on 7 Dec 2020
Working with strings/cell is easier.
T = readtable('agree');
header = T.Properties.VariableNames; % keep table variable names
T = string(T{:, :}); % convert to string
yesIdx = ismember(T, {'Agree', 'Strongly Agree'}); % index of YES answers
T(yesIdx) = 1; T(~yesIdx) = 0; % assign 1/0 values
T = array2table(T, 'VariableNames', header); % convert back to table
I also notice strcmpi in your example above. If you are looking for case insensitive situations, you can further change 4th line to:
yesIdx = ismember(lower(T), {'agree', 'strongly agree'}); % index of YES answers
  5 Comments
Farrah Vogel-Javeri
Farrah Vogel-Javeri on 8 Dec 2020
That's fantastic thanks! Do you know how I'd go about adapting the code to be able to cope with an array of data that also has dates and time in it? Could I somehow build it so that it returns the other cploumns with non-likart data as is, but just change the likart data?

Sign in to comment.

More Answers (1)

Ameer Hamza
Ameer Hamza on 7 Dec 2020
Convert your code into a function like this
function y = myFunc(x)
x(strcmpi(x,'Agree')) = {1}; %% change all results in column called Q1 to 1 if agree appears
x(strcmpi(x,'Strongly Agree')) = {1}; %% change all results in column called Q1 to 1 if strongly agree appears
x(strcmpi(x,'Disagree')) = {0}; %% change all results in column called Q1 to 0 if disagree appears
x(strcmpi(x,'Neither Agree Nor Disagree')) = {0};%% change all results in column called Q1 to 0 if neither agree nor disagree appears
x(strcmpi(x,'Strongly Disagree')) = {0}; %% change all results in column called Q1 to 0 if strongly disagree appears
x(strcmpi(x,"Don't know")) = {0} %% change all results in column called Q1 to 0 if Don't know appears
end
and then try this
T;
T_new = varfun(@myFunc, T)
  1 Comment
Farrah Vogel-Javeri
Farrah Vogel-Javeri on 7 Dec 2020
Thanks so much! I'm still very new to matlab, so could you explain the last part of the code to me please? When should I call the function to input which column it needds to look at?

Sign in to comment.

Products


Release

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!