frequently used function for table variable

I have a table with many temperature variables in C and I wanted to convert it into F using fuction. So I created following but it does not seems to work. Any way to create a function which are kind of common conversion which can be used again and again.
function Table_CtoF(T,OldVariable,NewVariable)
T.(NewVariable) = (T.(OldVariable)*9/5)+32;
end

 Accepted Answer

I am not certain what ‘T’ looks like.
Something like this would work —
T = table(randi([-40 40],5,1),'VariableNames',{'OldVariable'})
T = 5×1 table
OldVariable ___________ -6 11 37 -12 -34
T.NewVariable = Table_CtoF(T)
T = 5×2 table
OldVariable NewVariable ___________ ___________ -6 21.2 11 51.8 37 98.6 -12 10.4 -34 -29.2
function NewVariable = Table_CtoF(T)
NewVariable = (T.('OldVariable')*9/5)+32;
end
The single quotes are important when using this sort of variable addressing.

10 Comments

Looks promising... But how are we passing on the 'OldVariable' name in function call? Sorry I am little novice here.
No worries!
Because MATLAB table addressing syntax allows single-quoted strings (actually, character vectors) to be used within parentheses in variable name addressing in recent releases, pass it as a character vector.
T = table(randi([-40 40],5,1),'VariableNames',{'OldVariable'})
T = 5×1 table
OldVariable ___________ 15 0 30 4 -2
T.NewVariable = Table_CtoF(T,'OldVariable') % Variable Name Passed To Function As Character Vector
T = 5×2 table
OldVariable NewVariable ___________ ___________ 15 59 0 32 30 86 4 39.2 -2 28.4
function NewVariable = Table_CtoF(T,VarName)
NewVariable = (T.(VarName)*9/5)+32;
end
Here, the function uses the second argument as the character vector to refer to the specific variable.
.
Thanks it works. But I am now little greedy. I am trying to set the units also. so I modified function as below but it does not work
function NewVariable = Table_CtoF(T,m,n)
NewVariable = (T.(m)*9/5)+32;
T.Properties.VariableUnits{NewVariable} = {n};
end
I slightly improved the function, however the 'VariableUnits' property apparently has to be declared once, and cannot be subsequently amended. I tried every way possible to change it to add to the cell array (indexing and concatenation) or as string variables, and it always threw an error of the sort displayed here, trying it either in the function or in the calling workspace. (The presence or absence of the degree sign is irrelevant.)
There is nothing wrong with wanting it to work as you described, however there is siimply no way to make it work that way. (I left some of my unsuccessful attempts in the code for reference, as well as the only way to make it work.)
T = table(randi([-40 40],5,1),'VariableNames',{'OldVariable'})
T = 5×1 table
OldVariable ___________ -4 -5 34 25 27
T.Properties.VariableUnits = "°C";
n = "°F";
Units = T.Properties.VariableUnits
Units = 1×1 cell array
{'°C'}
T = Table_CtoF(T,'OldVariable','NewVariable') % Variable Name Passed To Function As Character Vector
T = 5×2 table
OldVariable NewVariable ___________ ___________ -4 24.8 -5 23 34 93.2 25 77 27 80.6
T.Properties.VariableUnits = {'°C','°F'} % Only This Works, And Only In This Position In The Code
T = 5×2 table
OldVariable NewVariable ___________ ___________ -4 24.8 -5 23 34 93.2 25 77 27 80.6
% T.Properties.VariableUnits = {Units,n}
T.Properties.VariableUnits
ans = 1×2 cell array
{'°C'} {'°F'}
function T = Table_CtoF(T,m,o) % 'm' = Old Variable Name, 'o' = New Variable Name
T.(o) = (T.(m)*9/5)+32;
end
.
The 'VariableUnits' property is just a cell array of the size of the number of variables in the table; you can manipulate it in any manner consistent with that definition.
You can't, of course, therefore, add the units before creating the new variable and you can't reference into the cell array by a string, just as you can't reference any other cell array by a string containing the content of the cell.
You CAN, however, do as I illustrated in the other Answer, locate where the given table variable is by string comparison functions and then modify that location. Again, of course, this has to be after the new variable has been created.
I don't see what is the "new and improved" function and where the desired code is in your last version, but to do what OP wants with the input syntax of new and old variable names and a units value to go with the new, the code to do so would be something like:
function T = Table_CtoF(T,old,new,units)
% create new variable in table "new" from "old" converting F to C and set
% new variable VariableUnits property to "units"
T.(new) = 1.8*T.(old)+32;
ixnew=find(matches(T.Properties.VariableNames,new));
T.Properties.VariableUnits(ixnew)={units};
end
I still think it would be better factorization for the function to operate on the data and leave the addressing of the table variables to the calling code instead of passing the table.
VariableUnits can be accessed or assigned using variable names, like this:
function T = table_CtoF(T,m,n,u)
T.(n) = (T.(m)*9/5)+32;
T.Properties.VariableUnits{n} = u;
end
Calling the function creates a new table variable, and assign its units:
T = table(randi([-40 40],5,1),'VariableNames',{'OldVariable'});
T = table_CtoF(T,'OldVariable','NewVariable','F');
T.Properties.VariableUnits
ans =
1×2 cell array
{0×0 char} {'F'}
Thanks, Duncan; I wasn't aware of that feature (obviously), although I see it is documented now that reread the doc. It's not made at all clear that works in any of the examples, though; they are all just blanket assignments by position which is, probably, how I managed to overlook the obvious.
That does, indeed, make code simpler when don't need the extraneous lookup for the variable.
I wasn't/am still not sure just what syntax issues IA ran into; I didn't follow his discussion in seeing the problems he ran into...
Thanks Duncan, that is a neat solution. I tried on my table called as 'raw', but it gives error. Below is the error and function i created based on your solution.
>> Table_CtoF2(raw,'Water Out T (Avg)','Trail','deg F');
Error using Table_CtoF2 (line 4)
Unrecognized table variable name 'Trail'.
function T = Table_CtoF2(T,Old,New,Unit)
T.New = (T.(Old)*9/5)+32;
T.Properties.VariableUnits{New} = Unit;
end
T.New = (T.(Old)*9/5)+32;
should be
T.(New) = (T.(Old)*9/5)+32;
You created the variable "New", not the one of the string value in variable New
My bad. It works now. Thanks to all of you for great suggestions and solutions.

Sign in to comment.

More Answers (1)

Don't pass a table to your function, have it accept numeric inputs and return same; then just call it with the table names. Much more generic/useful that way.
>> which -all C2F
C:\Users\Duane\Documents\MATLAB\Utilities\C2F.m
>> type C2F
function F=C2F(C)
% convert degree C to F
F=1.8*C+32;
end
>>
Usage in your case would be something like
T.F=C2F(T.C);
if your table is T and the centigrade temperature variable is "C"
I'd be more tempted to use something like
T.C=C2F(T.C); % store temperature F in original variable
ixC=find(matches(T.Properties.VariableNames,'C')); % find which variable index it is
T.Properties.VariableNames(ixC)='F'; % label it as 'F' instead
so as to not carry but the one temperature variable.

Categories

Find more on MATLAB in Help Center and File Exchange

Products

Release

R2020a

Community Treasure Hunt

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

Start Hunting!