In a table, when I try assigning a value to a new column based on some criteria, I get error that "assignment to elements using simple assignment statement is not supported"

I have a table for which I create an index where the values in a particular column are not NaN. I then try to use this index to create an entry into a new array and replace the values at the corresponding index (preloaded with '0000') with '0001'. I will then add this array to the table as a new column.
My intention is to fill the corresponding indx in the column with '0001', if the value in the newTable.PEM1_GA_Current_Estimate_Error a valid number (not NaN).
PEM1b ='0001';
PEM2b ='0010';
PEM3b = '0100';
PEM4 = '1000';
temp={};
indx=(find(newTable.PEM1_GA_Current_Estimate_Error ~= NaN))
temp ={repmat('0000',size(newTable,1),1)}
temp{indx} = PEM1b
%...and add this array as a new column to the table
the last assigment in the code above generates this error:
Assigning to 2609 elements using a simple assignment statement is not supported. Consider using comma-separated list assignment.
I don't think I should need a for loop to iterate through each row and replace the value at the "indx" location --what am I doing wrong?
I included the data....thank you.

3 commentaires

Don't use == or ~= to compare to NaN, because NaN is not equal to NaN.
Consider this vector x:
x = [1 NaN 3 NaN 5];
Checking that each element of x is not equal to (~=) NaN indicates that all elements of x are non-NaN, which is obviously not the case.
x ~= NaN
ans = 1x5 logical array
1 1 1 1 1
That happens because NaNs are considered not equal to each other (so NaN ~= NaN is true):
NaN ~= NaN
ans = logical
1
Instead, use the isnan() function to determine whether each element of an array is NaN, as in:
~isnan(x)
ans = 1x5 logical array
1 0 1 0 1
newTable = load('data.mat').newTable
newTable = 2609x17 table
LPE_VBAT PEM1_LPE_ZM PEM1_LPE_EXP_GA_CURR PEM1_INVERTER_CURRENT PEM1_GA_Current_Estimate_Error PEM2_LPE_ZM PEM2_LPE_EXP_GA_CURR PEM2_INVERTER_CURRENT PEM2_GA_Current_Estimate_Error PEM3_LPE_ZM PEM3_LPE_EXP_GA_CURR PEM3_INVERTER_CURRENT PEM3_GA_Current_Estimate_Error PEM4_LPE_ZM PEM4_LPE_EXP_GA_CURR PEM4_INVERTER_CURRENT PEM4_GA_Current_Estimate_Error ________ ___________ ____________________ _____________________ ______________________________ ___________ ____________________ _____________________ ______________________________ ___________ ____________________ _____________________ ______________________________ ___________ ____________________ _____________________ ______________________________ 0 0 0 -1.43 NaN 0 0 9.73 NaN 0 0 -0.478 NaN 5.41 129 109 NaN 530 4.21 126 2.62 NaN 4.65 114 46.7 2.4411 0 0 -0.356 NaN 5.06 105 1.97 NaN 530 4.21 126 66.3 1.9005 0 0 -0.343 NaN 0 0 -0.546 NaN 5.06 105 57.7 NaN 531 4.91 108 97.4 1.1088 4.49 118 109 1.0826 0 0 -1.1 NaN 4.19 127 110 NaN 590 4.62 128 -1.27 NaN 5.3 111 65.3 1.6998 0 0 -0.515 NaN 5.26 112 35.8 NaN 535 5.76 93 39.7 2.3426 5.3 101 66.9 1.5097 0 0 -0.171 NaN 5.06 106 3.26 NaN 535 5.76 93 82.1 1.1328 5.3 101 91 1.1099 0 0 -0.222 NaN 0 0 0.454 NaN 524 5.93 88.4 76.3 1.1586 6.45 81.2 73.7 1.1018 0 0 -0.761 NaN 6.25 84 69.8 NaN 589 5.33 110 3.21 NaN 0 0 0.0767 NaN 0 0 -0.152 NaN 4.99 118 36.7 NaN 0 0 0 -1.37 NaN 0 0 5.44 NaN 0 0 -0.0206 NaN 5 138 14.2 NaN 0 0 0 -1.31 NaN 0 0 5.31 NaN 0 0 -0.27 NaN 5.1 136 60.5 NaN 589 4.62 127 87.4 1.4531 4.71 125 85.7 1.4586 0 0 -0.212 NaN 4.82 122 79.9 NaN 0 0 0 -1.61 NaN 4.71 125 85.7 1.4586 0 0 -0.00285 NaN 4.82 122 79 NaN 523 4.6 114 -1.47 NaN 4.6 114 47.8 2.3849 0 0 -0.401 NaN 5.8 90.2 1.99 NaN 597 6.78 88 -1.32 NaN 6.96 85.8 49.5 1.7333 0 0 -0.428 NaN 7.21 82.8 32.7 NaN 597 6.78 88 76.8 1.1458 6.96 85.8 72.6 1.1818 0 0 -0.158 NaN 0 0 0.357 NaN
PEM1b = '0001';
indx = ~isnan(newTable.PEM1_GA_Current_Estimate_Error);
temp = repmat({'0000'},size(newTable,1),1);
temp(indx) = {PEM1b}
temp = 2609x1 cell array
{'0000'} {'0000'} {'0001'} {'0001'} {'0000'} {'0001'} {'0001'} {'0001'} {'0000'} {'0000'} {'0000'} {'0001'} {'0000'} {'0000'} {'0000'} {'0001'} {'0000'} {'0001'} {'0000'} {'0000'} {'0000'} {'0000'} {'0001'} {'0001'} {'0001'} {'0001'} {'0001'} {'0001'} {'0001'} {'0001'}
%...and add this array as a new column to the table
newTable.newColumn = temp
newTable = 2609x18 table
LPE_VBAT PEM1_LPE_ZM PEM1_LPE_EXP_GA_CURR PEM1_INVERTER_CURRENT PEM1_GA_Current_Estimate_Error PEM2_LPE_ZM PEM2_LPE_EXP_GA_CURR PEM2_INVERTER_CURRENT PEM2_GA_Current_Estimate_Error PEM3_LPE_ZM PEM3_LPE_EXP_GA_CURR PEM3_INVERTER_CURRENT PEM3_GA_Current_Estimate_Error PEM4_LPE_ZM PEM4_LPE_EXP_GA_CURR PEM4_INVERTER_CURRENT PEM4_GA_Current_Estimate_Error newColumn ________ ___________ ____________________ _____________________ ______________________________ ___________ ____________________ _____________________ ______________________________ ___________ ____________________ _____________________ ______________________________ ___________ ____________________ _____________________ ______________________________ _________ 0 0 0 -1.43 NaN 0 0 9.73 NaN 0 0 -0.478 NaN 5.41 129 109 NaN {'0000'} 530 4.21 126 2.62 NaN 4.65 114 46.7 2.4411 0 0 -0.356 NaN 5.06 105 1.97 NaN {'0000'} 530 4.21 126 66.3 1.9005 0 0 -0.343 NaN 0 0 -0.546 NaN 5.06 105 57.7 NaN {'0001'} 531 4.91 108 97.4 1.1088 4.49 118 109 1.0826 0 0 -1.1 NaN 4.19 127 110 NaN {'0001'} 590 4.62 128 -1.27 NaN 5.3 111 65.3 1.6998 0 0 -0.515 NaN 5.26 112 35.8 NaN {'0000'} 535 5.76 93 39.7 2.3426 5.3 101 66.9 1.5097 0 0 -0.171 NaN 5.06 106 3.26 NaN {'0001'} 535 5.76 93 82.1 1.1328 5.3 101 91 1.1099 0 0 -0.222 NaN 0 0 0.454 NaN {'0001'} 524 5.93 88.4 76.3 1.1586 6.45 81.2 73.7 1.1018 0 0 -0.761 NaN 6.25 84 69.8 NaN {'0001'} 589 5.33 110 3.21 NaN 0 0 0.0767 NaN 0 0 -0.152 NaN 4.99 118 36.7 NaN {'0000'} 0 0 0 -1.37 NaN 0 0 5.44 NaN 0 0 -0.0206 NaN 5 138 14.2 NaN {'0000'} 0 0 0 -1.31 NaN 0 0 5.31 NaN 0 0 -0.27 NaN 5.1 136 60.5 NaN {'0000'} 589 4.62 127 87.4 1.4531 4.71 125 85.7 1.4586 0 0 -0.212 NaN 4.82 122 79.9 NaN {'0001'} 0 0 0 -1.61 NaN 4.71 125 85.7 1.4586 0 0 -0.00285 NaN 4.82 122 79 NaN {'0000'} 523 4.6 114 -1.47 NaN 4.6 114 47.8 2.3849 0 0 -0.401 NaN 5.8 90.2 1.99 NaN {'0000'} 597 6.78 88 -1.32 NaN 6.96 85.8 49.5 1.7333 0 0 -0.428 NaN 7.21 82.8 32.7 NaN {'0000'} 597 6.78 88 76.8 1.1458 6.96 85.8 72.6 1.1818 0 0 -0.158 NaN 0 0 0.357 NaN {'0001'}
yes! I found out about the isnan after the fact. Thanks as always for your great help.

Connectez-vous pour commenter.

 Réponse acceptée

"I don't think I should need a for loop to iterate through each row and replace the value at the "indx" location"
You do not need a loop, just assign a scalar cell array to the existing cell array using parentheses:
temp(indx) = {PEM1b};
"what am I doing wrong?"
You are trying to assign one array to multiple cells of the cell array. You could think of it something like this:
[a,b,c,d,e,f,..] = pi
While this might be a defined syntax in some languages, with MATLAB this does not assign one array to lots of cells (or variables or fields or ...). In general it is an error. You could use DEAL for some of those situations, but your usecase is actually much simpler: you can use the special case that applies for any array type: a scalar on the RHS will always be expanded to fit the indexing on the LHS into an array of the same type. So all you need is a scalar cell array on the RHS. Which means that the LHS must use parentheses to assign to the cell array itself, not curly braces to replace its content. Then you assign a scalar array element on the RHS to as many elements on the LHS as the indexing specifies (note how I did not write cell, because this concept is exactly the same for every array class).

8 commentaires

C = num2cell('a':'i')
C = 1x9 cell array
{'a'} {'b'} {'c'} {'d'} {'e'} {'f'} {'g'} {'h'} {'i'}
C([2,8]) = {'xxx'} % assign scalar to array
C = 1x9 cell array
{'a'} {'xxx'} {'c'} {'d'} {'e'} {'f'} {'g'} {'xxx'} {'i'}
[C{[3,7]}] = deal('yyy') % comma-separated list
C = 1x9 cell array
{'a'} {'xxx'} {'yyy'} {'d'} {'e'} {'f'} {'yyy'} {'xxx'} {'i'}
C{[4,6]} = 'zzz' % error
Assigning to 2 elements using a simple assignment statement is not supported. Consider using comma-separated list assignment.
I could have sworn I tried that! Thank you!
ah...this is the error I got when I had tried that before:
Conversion to char from cell is not possible.
Error in ProcessLPEfieldData (line 97)
temp(indx) = {PEM1b}
here's the code...
% Compute actual vs. estimate error, add to table for each PEM
% PEM1
errorarray= newTable.PEM1_LPE_EXP_GA_CURR./newTable.PEM1_INVERTER_CURRENT;
newTable = addvars(newTable,errorarray,'NewVariableNames','PEM1_GA_Current_Estimate_Error','After',4)
% PEM2
errorarray= newTable.PEM2_LPE_EXP_GA_CURR./newTable.PEM2_INVERTER_CURRENT;
newTable = addvars(newTable,errorarray,'NewVariableNames','PEM2_GA_Current_Estimate_Error','After',8)
% PEM3
errorarray= newTable.PEM3_LPE_EXP_GA_CURR./newTable.PEM3_INVERTER_CURRENT;
newTable = addvars(newTable,errorarray,'NewVariableNames','PEM3_GA_Current_Estimate_Error','After',12)
% PEM4
errorarray= newTable.PEM4_LPE_EXP_GA_CURR./newTable.PEM4_INVERTER_CURRENT;
newTable = addvars(newTable,errorarray,'NewVariableNames','PEM4_GA_Current_Estimate_Error','After',16)
% Clean up Data
indx =find(newTable.PEM1_INVERTER_CURRENT < 10);
newTable.PEM1_GA_Current_Estimate_Error(indx) = NaN;
indx =find(newTable.PEM2_INVERTER_CURRENT < 10);
newTable.PEM2_GA_Current_Estimate_Error(indx) = NaN;
indx =find(newTable.PEM3_INVERTER_CURRENT < 10);
newTable.PEM3_GA_Current_Estimate_Error(indx) = NaN;
indx =find(newTable.PEM4_INVERTER_CURRENT < 10);
newTable.PEM4_GA_Current_Estimate_Error(indx) = NaN;
% Errors based on Complement of PEMs active
PEM1b ='0001';
PEM2b ='0010';
PEM3b = '0100';
PEM4 = '1000';
%save([datapath 'data.mat'],'newTable')
temp=[];
indx=(find(newTable.PEM1_GA_Current_Estimate_Error ~= NaN))
temp =[repmat('0000',size(newTable,1),1)]
temp(indx) = {PEM1b}
newTable=addvars(newTable,temp,'NewVariableNames', 'Module 1', 'After',1)
What you showed in your question:
temp={};
temp ={repmat('0000',size(newTable,1),1)}
What you showed in your comment:
temp=[];
temp =[repmat('0000',size(newTable,1),1)]
They are completely different things:
  • in your question you create a cell array (which is a container array) and put things into it.
  • in your comment you create a character matrix (which is NOT a container array).
I could give you a box with an apple in it. Or I could give you an apple. But they are not the same thing: you cannot have a command which says "replace the content of the apple with a banana". But you can do that with the box.
A table is a container array, it may contain a character matrix. So from that point of view, you could use either.
But if you use a character matrix then you need to use parentheses indexing to refer to those characters themselves (not some inappropriate curly-brace indexing as if those characters were stored inside containers, which in your comment they are not). Using the character matrix will be more effort because you are not allocating a scalar array on the RHS, you are now attempting to allocate a vector (i.e. multiple elements) which means that you will need the number of elements on the LHS and the RHS to match exactly, which will mean that you will need to use e.g. REPMAT or similar on the RHS. You will most likely need to use subscript indexing or perform some conversion to linear indexing, which would take a few lines of code... and so your code will be more complex and more liable to bugs...
It would be simpler to stick with a cell array of character vectors, just like you showed in your question.
Or perhaps even better, a string array.
Also: if you use a character matrix get rid of those superfluous square brackets:
temp=[]; % <- this does nothing, get rid of it.
temp =[repmat('0000',size(newTable,1),1)]
% ^ superfluous, get rid of them ^
thank you for the detailed explanation. Much appreciated! I ended up going with the string array. However, I don't fully understand this....I first tried
temp=[];
indx=find(not(isnan(newTable.PEM1_GA_Current_Estimate_Error)));
temp =repmat("0000",size(newTable,1),1);
temp(indx) = {char(PEM1b)};
newTable=addvars(newTable,temp,'NewVariableNames', 'Module 1', 'After',1)
which seemed to work. But I didn't understand why it would....
I ended up with
temp(indx) = PEM1b
which to me makes more sense. can you explain what I "did" here? maybe this will help me get it!
thanks!
"which seemed to work. But I didn't understand why it would...."
Unlike some other languages, type coercion in MATLAB was in the past basically limited to the numeric types and char. For better or for worse, modern users apparently expect type coercion between everything, so the (relatively new) string class can coerce numeric, char, and cell-of-char into strings:
S = "this" % string
S = "this"
S(2) = 'assigns' % char
S = 1x2 string array
"this" "assigns"
S(3) = 3 % numeric
S = 1x3 string array
"this" "assigns" "3"
S(4) = {'types'} % cell of char
S = 1x4 string array
"this" "assigns" "3" "types"
"which to me makes more sense. can you explain what I "did" here?"
You created a string array and then assigned a character vector to it, which got coerced into a string:
T = ["hello";"x"]
T = 2x1 string array
"hello" "x"
T(2) = 'world'
T = 2x1 string array
"hello" "world"
Using a scalar string on the RHS would not use any coercion.
I really appreciate you taking the time to explain. I get it now. Thank you!

Connectez-vous pour commenter.

Plus de réponses (0)

Produits

Version

R2023b

Community Treasure Hunt

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

Start Hunting!

Translated by