Replace strings with a different string and save the data
5 views (last 30 days)
Show older comments
I have a file for atomic coordinates, where I wanted to replace the 'c' with a certain pertange of maerials 'Fe', 'Al', 'Au'. The column C needs to be replaced with 40% Fe, 30% Al and 30% Au. Nothing else changes. The rest of the files stays same. I also plan to extend this to more elements lets say, Fe, Al, Ni, Cu, Zr all 20% each. I have attached a sample file. Below is a exceprt from the file. I will really appreciate any suggestions.
168
generated by VMD
C 0.000000 0.000000 0.000000
C -0.866025 0.500000 0.000000
C -0.866025 1.500000 0.000000
C 0.000000 2.000000 0.000000
C 1.732051 0.000000 0.000000
C 0.866025 0.500000 0.000000
C 0.866025 1.500000 0.000000
C 1.732051 2.000000 0.000000
C 3.464102 0.000000 0.000000
C 2.598076 0.500000 0.000000
0 Comments
Answers (2)
VBBV
on 9 Dec 2023
Edited: VBBV
on 9 Dec 2023
D = readtable('data.txt');
C = char(['40% Fe';'30% Al']) % e.g. element data to be filled in 1st column
D.(1) = repmat(C,168/2,1) % replace 1st column of the table with element data
2 Comments
VBBV
on 9 Dec 2023
You can rpleace the 1st column of the datatable with percentage of elements you want as vector shown above
Voss
on 21 Dec 2023
I assume that you want to replace the C's with the specified elements (e.g., Fe, Al, Ni) at random according to the specified proportions (e.g., 40, 30, 30).
% name of the original file:
filename = 'graphene.txt';
% name of the new file that will be created, with the new elements in the
% specified (approximate) proportions:
new_filename = 'graphene_modified.txt';
% elements to replace the "C"s with:
elements = ["Fe","Al","Ni"];
% (approximate) proportion of each element to use:
proportions = [40,30,30];
% show the original file's contents, for reference:
dbtype(filename)
% read the file into string array L, each element of which is a line of
% text from the file:
L = readlines(filename);
% fidx: indices of the lines that start with " C":
fidx = find(startsWith(L," C"));
% total number of lines that will be altered:
N_lines = numel(fidx);
% number of lines that will be altered, for each element:
N = round(proportions/sum(proportions)*N_lines);
% enforce that sum(N) == N_lines:
N(end) = N_lines-sum(N(1:end-1));
% permute fidx to get a random replacement order:
fidx = fidx(randperm(N_lines));
% get the start and end index (in fidx) for each element:
temp = cumsum([0 N]);
s_idx = temp(1:end-1)+1;
e_idx = temp(2:end);
% loop over elements and replace the "C"s:
for ii = 1:numel(elements)
% indices of the random lines of text that will be changed to
% element(ii):
idx = fidx(s_idx(ii):e_idx(ii));
% replace "C" with element(ii) in those lines:
L(idx) = replace(L(idx),"C",elements(ii));
end
% write the result to a new file:
writelines(L,new_filename)
% verification: check the new file's contents:
dbtype(new_filename)
% verification: read the new file and verify that each element starts the
% expected number of lines:
new_L = readlines(new_filename);
for ii = 1:numel(elements)
assert(nnz(startsWith(new_L," "+elements(ii))) == N(ii), ...
sprintf('Unexpected number of "%s" lines',elements(ii)));
end
0 Comments
See Also
Categories
Find more on Logical in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!