What is the best way to add empty rows to an existing table, to pre-allocate for more data?

조회 수: 154 (최근 30일)
Let's say I have a table that has 100 rows of ten variables and now I know I am going to need another 100 rows (or perhaps 100,000) in this table. To avoid loads of copying, I should preallocate these rows before populating them. The variables can be of various different types. I tried doing the following without success:
T{101:200,:} = missing;
I also tried:
T(101:200,:) = cell(100, width(T));
"Conversion to char from cell is not possible."
I just want the equivalent of T.addemptyrows(100). Or, if Matlab had an emptyrow(T) function, I could do:
T(101:200,:) = emptyrow(T)
Here's a toy example to play with:
T = table(["One"; "Two"; "Three"], [1; 2; 3], ['the'; 'cat'; 'sat'], {{1 2 3}; {4 5 6}; {7 8 9}})
T{4:10,:} = missing
Error using {}
Unable to perform assignment because value of type 'missing' is not convertible to 'char'.
Caused by:
Error using char
Conversion to char from missing is not possible.
If I remove the char variable, the same happens with cell.
I considered that I could take the first line of the table and duplicate it 100 times, then overwrite it one line at a time, but this is very inefficient, because cells could contain large amounts of data when all I really want is an empty variable. Additionally, this could hide errors since cells could appear to be populated with viable data when they wouldn't have been, and also could pose serious privacy and security risks in some scenarios.
I could, presumably, write a function that loops through the variable types of each and every variable in the existing table, and then creates a new table of the approriate size and variable types, and then copies the variable names from the first table, and then joins the two tables together, but that is a mess. I also worry about clobbering existing meta data or column data (since several variables could be in one column) and other issues I'm not even aware of. Is there not a more elegant solution? This must be a common thing to need to do. Thanks!

채택된 답변

Matt J
Matt J 2024년 1월 8일
T = table(["One"; "Two"; "Three"], [1; 2; 3], ['the'; 'cat'; 'sat'], {{1 2 3}; {4 5 6}; {7 8 9}})
T = 3×4 table
Var1 Var2 Var3 Var4 _______ ____ ____ __________ "One" 1 the {1×3 cell} "Two" 2 cat {1×3 cell} "Three" 3 sat {1×3 cell}
newlength=10;
T(newlength+1,:)=T(1,:);
T(end,:)=[]
T = 10×4 table
Var1 Var2 Var3 Var4 _________ ____ ____ ____________ "One" 1 the {1×3 cell } "Two" 2 cat {1×3 cell } "Three" 3 sat {1×3 cell } <missing> 0 {0×0 double} <missing> 0 {0×0 double} <missing> 0 {0×0 double} <missing> 0 {0×0 double} <missing> 0 {0×0 double} <missing> 0 {0×0 double} <missing> 0 {0×0 double}
  댓글 수: 4
Leon
Leon 2024년 1월 8일
"Copying cells doesn't result in any new memory consumption. It's all done with pointers."
That's great, I didn't realise that. So your solution is very good. Thanks!
Matt J
Matt J 2024년 1월 8일
You're welcome, but if it resolves your question, please Accept-click the answer.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Voss
Voss 2024년 1월 7일
편집: Voss 2024년 1월 7일
T = table(["One"; "Two"; "Three"], [1; 2; 3], ['the'; 'cat'; 'sat'], {{1 2 3}; {4 5 6}; {7 8 9}})
T = 3×4 table
Var1 Var2 Var3 Var4 _______ ____ ____ __________ "One" 1 the {1×3 cell} "Two" 2 cat {1×3 cell} "Three" 3 sat {1×3 cell}
T{end+100,1} = missing % add 100 rows
Warning: The assignment added rows to the table, but did not assign values to all of the table's existing variables. Those variables are extended with rows containing default values.
T = 103×4 table
Var1 Var2 Var3 Var4 _________ ____ ____ ____________ "One" 1 the {1×3 cell } "Two" 2 cat {1×3 cell } "Three" 3 sat {1×3 cell } <missing> 0 {0×0 double} <missing> 0 {0×0 double} <missing> 0 {0×0 double} <missing> 0 {0×0 double} <missing> 0 {0×0 double} <missing> 0 {0×0 double} <missing> 0 {0×0 double} <missing> 0 {0×0 double} <missing> 0 {0×0 double} <missing> 0 {0×0 double} <missing> 0 {0×0 double} <missing> 0 {0×0 double} <missing> 0 {0×0 double}
  댓글 수: 8
Voss
Voss 2024년 1월 8일
"is there a special comment that can be added to that one line to suppress the warning?"
Not a comment, but a command. The warning function can be used to turn on and off individual warning messages by ID. To get the ID you can use the lastwarn function.
Demonstration: First, generate the warning in question:
T = table(["One"; "Two"; "Three"], [1; 2; 3], ['the'; 'cat'; 'sat'], {{1 2 3}; {4 5 6}; {7 8 9}});
T{end+100,1} = missing; % warning is issued
Warning: The assignment added rows to the table, but did not assign values to all of the table's existing variables. Those variables are extended with rows containing default values.
Get the warning ID using lastwarn:
[~,wid] = lastwarn()
wid = 'MATLAB:table:RowsAddedExistingVars'
Turn the warning off:
warning('off',wid)
Verify that it worked by trying to generate the same warning again:
T{end+100,1} = missing; % no warning this time
Now that you know the relevant warning ID, in your code you can turn off the warning before any are generated:
warning('off','MATLAB:table:RowsAddedExistingVars')
Leon
Leon 2024년 1월 8일
편집: Leon 2024년 1월 8일
Thanks re. info about lastwarn and warning.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Logical에 대해 자세히 알아보기

제품


릴리스

R2023a

Community Treasure Hunt

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

Start Hunting!

Translated by