MATLAB Answers

Changing variable name from input string

40 views (last 30 days)
Ewan
Ewan on 9 Jan 2020
Edited: Adam Danz on 9 Jan 2020
I have some code that processes experimental data of mine and saves a variable, Depth, to the workspace. I would like to include some lines that would ask the user for an input string, say NewName and use this as the name for Depth, while retaining all the data in the array. I'd rather not have to rename every instance of Depth in my code as I want to use this on other data sets and have unique names for the variable in each case.
So far I have:
prompt = 'What would you like to rename Depth?';
str = input(prompt,'s');
if (isempty(str) == 1)
str = 'Depth';
end
str = Depth;
so that if the input is empty, then Depth is not renamed. However, this only creates a new array str with the same values as Depth, and does not rename Depth or even create a new array, NewName, with the same values as Depth.
Is there any way to solve this or work around it?

  2 Comments

Stephen Cobeldick
Stephen Cobeldick on 9 Jan 2020
"Is there any way to solve this..:"
Yes, but only if you want to force yourself into writing slow, complex, obfuscated, buggy code that is hard to debug. Read this to know why:
":.. or work around it?"
Simply use a container array: a cell array, a structure, a table, etc.
Adam Danz
Adam Danz on 9 Jan 2020
In case you need a second opinion, Stephen is, of course, correct that this type of dynamic variable naming will open a can or worms. Here's a quick example of how you can store the user's variable name.
prompt = 'What would you like to rename Depth? '; % add space at end
str = input(prompt,'s');
if isempty(str) % no need for equality testing
str = 'Depth';
end
varnames{n} = str; % store the variable name in a cell array
vars{n} = value; % store the values for that variable is a 2nd cell array
Now when you want to access the variables.
varIdx = strcmp(varnames, 'Depth');
vars{varIdx}

Sign in to comment.

Answers (3)

Steven Lord
Steven Lord on 9 Jan 2020
Rather than using eval or storing your "variable names" and your values separately, if the names are valid MATLAB identifiers you could store them in a struct array using dynamic field names.
mydata = struct();
for k = 1:10
name = "Variable" + k;
mydata.(name) = k.^2;
end
mydata
If they're not valid MATLAB identifiers and you're using release R2019b or later you could store your data in a table array. Alternately you could use a containers.Map to store the data with each "variable name" as the key.

  3 Comments

Stephen Cobeldick
Stephen Cobeldick on 9 Jan 2020
"if the names are valid MATLAB identifiers ..."
Do not underestimate the importance of this requirement!
Using a cell array as Adam Danz proposed works in any version since MATLAB 5.0 (back in 1996), and allows the names to contain any characters at all, making a cell array a very robust solution.
Steven Lord
Steven Lord on 9 Jan 2020
Using a cell array would work, but it does require the users to strcmp when retrieving data and runs the risk of have two sets of data with the same name in the cell array. If you were to store the names and data in a cell array with two columns (first for names, second for data) rather than two separate cell arrays you'd also reduce the chances of the names and data arrays getting out of sync (adding a name to the name cell but forgetting to update the values cell or vice versa, for example.)
Adam Danz
Adam Danz on 9 Jan 2020
The two column cell array would definitely be better than having two variables. The input name could also be checked for uniqueness.
isNotUnique = true;
prompt = 'What would you like to rename Depth? ';
C = {'a', 1:5; 'b', 2:10};
values = 5:50; % the values that will be associated with new variable
% Keep asking for variable name until the name is unique
while isNotUnique
str = input(prompt,'s');
isNotUnique = ismember(str,C(:,1));
prompt = 'Variable name taken. Choose a unique name. ';
end
% Store new variable
C(3,:) = {str, values};

Sign in to comment.


Adam Danz
Adam Danz on 9 Jan 2020
Edited: Adam Danz on 9 Jan 2020
For visibility, I've summarized my comments here as an answer.
This demo asks the user for a variable name and stores the variable name along with the associated values in an nx2 cell array with the variable names in column 1 and values in column 2. If the variable name is taken or empty, the user will be prompted again to create a variable name. The variable name can unconventionally be any combination of characters.
prompt = 'What would you like to rename Depth? ';
C = {'a', 1:5; 'b', 2:10}; % nx2 array of {variableNames, values}
values = 5:50; % This is the value we're currently naming
isNotUnique = true;
% Ask user for a unique, nonempty variable name
while isNotUnique
str = input(prompt,'s');
isNotUnique = ismember(str,C(:,1)) || isempty(str);
prompt = 'Variable name taken or was empty. Choose a unique name. ';
end
% Store new var-name and it's associated value
C(3,:) = {str, values};
% or C(end+1,:) = {str, values};
To access the case-sensitive variable named 'a' by the user,
C{strcmp(C(:,1), 'a'),2}
To access the n_th variable
C{n,2}

  0 Comments

Sign in to comment.


Ruger28
Ruger28 on 9 Jan 2020
Chiming in for a 3rd opinion. I have used this in the past succesfully.
Depth = [1:100];
prompt = 'What would you like to rename Depth?';
str = input(prompt,'s');
if ~isempty(str)
eval([str, ' =Depth;']); % rename if there is a string
end

  4 Comments

Show 1 older comment
Ewan
Ewan on 9 Jan 2020
I appreciate your quick responses, and I can see now that simply creating a cell array to store the variable name(s) is much easier. Thanks for the link to some handy documentation Stephen!
Ruger28
Ruger28 on 9 Jan 2020
Stephen - I use the method of structures, but I was simply answering the OP's question the way they described their issue and desired outcome.
Adam Danz
Adam Danz on 9 Jan 2020
Yes, but the point is to steer the OPs away from bad practices. It's the XY problem. The OP is asking for a solution that s/he thinks is a good solution to the problem. But focus should be placed on the problem itself, not on what the OP thinks the best solution is to the problem.

Sign in to comment.