Strings to variable names

78 visualizaciones (últimos 30 días)
Milos Krsmanovic
Milos Krsmanovic el 23 de Ag. de 2021
Comentada: Milos Krsmanovic el 30 de Ag. de 2021
I have a table with 30-ish columns and thousands of rows containing strings and numerical values (small sample attached). I need to plot hundreds of different figures by matching certain criteria and extracting only portion of the data for each plot, based on that criteria. I would like to do this by passing two variables (matching the .Properties.VariableNames) to a function which would then do something based on these two input arguments.
I started reading on converting strings to variable names and found the deprecated function genvarname(), which points to matlab.lang.makeValidName() that takes string as the argument. But the latter gives me the error:
Unrecognized table variable name 'X'.
The way I'm trying to use it is by reading my data:
results = readtable('raw_data.csv','PreserveVariableNames',true);
then specifying which variable names I want to work with:
X = matlab.lang.makeValidName('Sigma');
Y = matlab.lang.makeValidName('LR');
However, trying to pass X and Y as the arguments to the function, then referencing them as follows:
results.X
is throwing me the error.
If I manually edit this call to results.Sigma or results.LR, everything works just fine. But changing these two variables inside of the function would defeat its purpose. I's like to keep X and Y as generalized variable names within the function and only change the two above lines before I call the function.
I'm also reading on dynamically generated variable names and why eval is a big no-no. I tried the alternative methods mentioned there, such as cell/ND-arrays or Structs, etc. but couldn't get that to work either.
Can someone point me to what the most appropriate method to solve this would be, please?
  8 comentarios
Stephen23
Stephen23 el 30 de Ag. de 2021
Editada: Stephen23 el 30 de Ag. de 2021
"What I opted out to do at the end is to use the modified solution from @Wan Ji - I created two new columns X and Y, without deleting/overwriting any of the existing ones. Before calling my function I will repopulate X and Y with whatever two columns I want to work with at that instance."
If you only need the data in those two columns, why do you have to add them back into the table? Surely you could just write your function to simply accept those two columns directly... which is also what you asked in your question "However, trying to pass X and Y as the arguments to the function...", so it is not clear to me why you now want to make this more complex than it needs to be (or even what you asked about).
Please show us the code you are trying now, I am sure that this could be simplified.
Milos Krsmanovic
Milos Krsmanovic el 30 de Ag. de 2021
I already expained why, in detail, in my previous comment.
Surely I would write the function to simply accept those two columns directly, which is also what I asked - if I knew how. Which is why I asked the question in the first place.
For the sake of other who might be reading this topic in the future, here is what I ended up with at the end.
Before the function:
results.X = results.LR;
results.Y = results.L;
Here I will change LR and L to any of the other 28 column names/headers for each instance when I'm calling the function.
Inside of the function:
for i = 1:e
data(1,i)=num2cell(mean(results.Xresults.Material==string(critMaterial(1)) & results.Sigma==string(critSigma(1)))));
data(2,i)=num2cell(mean(results.Y(results.Material==string(critMaterial(2)) & results.Sigma==string(critMaterial(1)))));
end

Iniciar sesión para comentar.

Respuesta aceptada

Wan Ji
Wan Ji el 23 de Ag. de 2021
Editada: Wan Ji el 23 de Ag. de 2021
Hi, try following code
results{:,'X'} = results{:,'Sigma'};
results(:,'Sigma') = [];
results{:,'Y'} = results{:,'LR'};
results(:,'LR') = [];
  3 comentarios
Milos Krsmanovic
Milos Krsmanovic el 26 de Ag. de 2021
Thanks for replying. I would like to keep the columns in the main table as they are being reused. Please see the additional example I provided to try and better explain my needs.
Milos Krsmanovic
Milos Krsmanovic el 29 de Ag. de 2021
I'm finally accepting this answer because it got me the closest to the working solution. The only difference I introduced was to not overwrite the existing columns, but to create additional two columns which I would overwrite at each instance I'm calling the function.
Thanks again.

Iniciar sesión para comentar.

Más respuestas (3)

per isakson
per isakson el 23 de Ag. de 2021
Editada: per isakson el 23 de Ag. de 2021
First a little exercise
%%
results = readtable('raw_data.csv');
results(4,:)
ans = 1×4 table
Material Sigma L LR ________ ________ _____ ___ {'PET'} {'Plus'} 0.149 522
%%
results.Properties.VariableNames{'Sigma'} = 'X';
results.Properties.VariableNames{'LR'} = 'Y';
results(4,:)
ans = 1×4 table
Material X L Y ________ ________ _____ ___ {'PET'} {'Plus'} 0.149 522
Like this you can rename the variables in the table (see also @Wan Ji comment), but AFAIK you cannot create alias, which I think is what you are asking for.
IMO, renaming variables will eventually cause confusion. A better way to achieve "I like to keep X and Y as generalized variable names within the function" is to define functions like
function foo( X, Y )
% do stuff with X and Y
end
and call them like
foo( results.Sigma, results.LR )
  2 comentarios
Milos Krsmanovic
Milos Krsmanovic el 26 de Ag. de 2021
Thank you for the answer. I didn't explain well that I don't want to rename the columns/property names in the main table. I provided additional example below to try and better describe my issue.
per isakson
per isakson el 27 de Ag. de 2021
"I don't want to rename the columns/property names in the main table" Yes and that's why I wrote: "[...] but AFAIK you cannot create alias, which I think is what you are asking for."

Iniciar sesión para comentar.


Stephen23
Stephen23 el 27 de Ag. de 2021
Editada: Stephen23 el 27 de Ag. de 2021
Mixing up unrelated topics has made you think that this is much more complex than it really is.
Look at your own code that you wrote in your question:
results.Sigma
results.LR
And then what you wrote after that: "If I manually edit this call to results.Sigma or results.LR, everything works just fine. But changing these two variables inside of the function would defeat its purpose."
So... then don't "change" them inside the function. Simply use strings to select the variables that you want (you specified here that you want to manually select the pairs of data that get plotted/analyzed), just as the MATLAB documentation explains:
Xs = ["Sigma", "Xpair2", "Xpair3", .. "XpairN"];
Ys = ["LR" , "Ypair2", "Ypair3", .. "YpairN"];
for k = 1:numel(Xs)
Xdata = results.(Xs(k));
Ydata = results.(Ys(k));
... whatever processing of Xdata and Ydata
end
So you can easily "manually" select and process any pairs of data that you want.
I see absolutely no reason why you need to copy-and-paste code hundreds of times.

Image Analyst
Image Analyst el 23 de Ag. de 2021
It's not just that using "eval() is a big no-no" like you said, it's that the whole concept of writing a program where you don't know the variable names in advance and are creating named variables based on strings or some other run-time input is a bad idea.
So it's bad period. It's not that eval() is the problem so you just need to find some other workaround or "alternative method" to do the bad thing. It's just not a good idea. I always thought it was obvious and didn't need much explanation, but maybe others have different ideas or don't understand the explanations.
See the FAQ for another discussion.
  1 comentario
Milos Krsmanovic
Milos Krsmanovic el 26 de Ag. de 2021
Fair point, poor choice of words from my end. Where I meant dynamically assigning the variable names I made it sound as if I'm talking about the eval() function per se. I added a small example below to better explain what I'm trying to do.

Iniciar sesión para comentar.

Categorías

Más información sobre Scripts en Help Center y File Exchange.

Productos


Versión

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by