Lua String concatenation - string

I am working on Lua and I have this kind of code
MapMessage(Process["ks.MSH"][1], MsgIn, mg)
MapEvent(Process["ks.EVN"][1], MsgIn, mg)
MapPatient(Process["ks.PID"][1], MsgIn, mg)
MapVisit(Process["ks.PV1"][1],MsgIn,mg)
In above statements, MapMessage, MapEvent, MapPatient, MapVisit are the functions and ks.MSH, ks.EVN, ks.PID, ks.PV1 are the tables in the database.
Now, I want to automate a part of this process using gmatch function provided in lua and I have this so far
for u in string.gmatch(S, "([^,%s]+)"), 1 do
l[k] = u
_G["Map"..l[k]](Process["ks[l[k]]"][1], R[1])
k=k+1
end
but the concatenation part in the third line of above code is not really making it ks.MSH, ks.PID, ks.PV1 e.t.c, so please suggest what needs to be there in place of (Process["ks[l[k]]"][1]to get s.MSH, ks.PID, ks.PV1 e.t.c

Since your string contains "MSH, PID, PV1, EVN", you'd have to use a hash-table or a lookup table. The program would be something like this:
S = "MSH, PID, PV1, EVN"
tLookup = {
MSH = "Message",
EVN = "Event",
PID = "Patient",
PV1 = "Visit",
}
for u in S:gmatch "([^,%s]+)" do
sNameOfFunction = tLoopup[u]
_G[ "Map"..sNameOfFunction ] ( Process["ks."..u][1], MsgIn, mg )
k=k+1
end
Or even something like this:
S = "MSH, PID, PV1, EVN"
tLookup = {
MSH = _G.MapMessage,
EVN = _G.MapEvent,
PID = _G.MapPatient,
PV1 = _G.MapVisit,
}
for u in S:gmatch "([^,%s]+)" do
tLoopup[u] ( Process["ks."..u][1], MsgIn, mg )
k = k+1
end

Here is what finally worked, thanks Egor and hjpotter92 :)
ks = {MSH = "ks.MSH", EVN = "ks.EVN", PID = "ks.PID", PV1 = "ks.PV1", PV2 = "ks.PV2"}
S = tostring(R[1].AllSegmentsList)
l = {}
k = 1
for u in string.gmatch(S, "([^,%s]+)") do
l[k] = u
_G["Map"..l[k]](Process[ks[l[k]]][1], MsgIn, mg)
k=k+1
end

Related

Does xlswrite have limitations?

I'm running MATLAB R2017a. I am trying to execute a simple program that writes 3 characters to an Excel file. When I run the program with a small number of values it is fine but when I increase it to the millions, the program pauses.
Does anyone know why the programming is pausing like this?
X = []
filename = 'PopltnFL.xlsx';
NumTrump = 4617886;
NumClinton = 4504975;
NumOther = 297025;
*% Values for which program runs without puasing*
% NumTrump = 4;
% NumClinton = 4;
% NumOther = 2;
%
for ii = 1:NumTrump
X = [X,'T'];
end
for jj = 1:NumClinton
X = [X,'C'];
end
for kk = 1:NumOther
X = [X,'O'];
end
X = X';
xlswrite(filename,X)

Alternative to nested loop

I am quite new to R scripting and I couldn't find any similar topic. I need to subset my 'dat' keeping all the rows that match with chr and ranges (start-end) in the 'regions' object.
I wrote a for loop but I think it is not the smartest solution in R and in addition it is very slow with big datasets.
Is there a faster alternative?
Thanks in advance for the replies.
regions <- cbind(chr = floor(runif(163,1,10))
, start = floor(runif(163,100,200))
, end = floor(runif(163,200,500)))
dat <- cbind(chr = floor(runif(20e6,1,22))
, pos = floor(runif(20e6, 1,10000)))
matched_index <- c()
for(i in 1:nrow(dat)) {
for(j in 1:nrow(regions)) {
if(dat[i,1] == regions[j,1]
& dat[i,2] >= regions[j,2]
& dat[i,2] <= regions[j,3])
{
matched_index <- c(matched_index, i)
print(i)
break
}
}
}
dat.filtered <- dat[matched_index,]

Compare to string of names

I am trying to compare the names of two strings, and trying to pick out the name that are not included in the other string.
h = 1;
for i = 1:name_size_main
checker = 0;
main_name = main(i);
for j = 1:name_size_image
image_name = image(j);
temp = strcmpi(image_name, main_name);
if temp == 1;
checker = temp;
end
end
if checker == 0
result(h) = main_name;
h = h+1;
end
end
but it keeps returning the entire string as result, the main string contain roughly 1000 names, the images name contain about 300 names, so it should return about 700 names in result but it keep returning all 1000 names.
I tried your code with small vectors:
main = ['aaa' 'bbb' 'ccc' 'ddd'];
image = ['bbb' 'ddd'];
name_size_main = size(main,2);
name_size_image = size(image,2);
h = 1;
for i = 1:name_size_main
checker = 0;
main_name = main(i);
for j = 1:name_size_image
image_name = image(j);
temp = strcmpi(image_name, main_name);
if temp == 1;
checker = temp;
end
end
if checker == 0
result(h) = main_name;
h = h+1;
end
end
I get result = 'aaaccc', is it not what you want to get?
EDIT:
If you are using cell arrays, you should change the line result(h) = main_name; to result{h} = main_name; like that:
main = {'aaa' 'bbb' 'ccc' 'ddd'};
image = {'bbb' 'ddd'};
name_size_main = size(main,2);
name_size_image = size(image,2);
result = cell(0);
h = 1;
for i = 1:name_size_main
checker = 0;
main_name = main(i);
for j = 1:name_size_image
image_name = image(j);
temp = strcmpi(image_name, main_name);
if temp == 1;
checker = temp;
end
end
if checker == 0
result{h} = main_name;
h = h+1;
end
end
You can use cells of string along with setdiff or setxor.
A = cellstr(('a':'t')') % a cell of string, 'a' to 't'
B = cellstr(('f':'z')') % 'f' to 'z'
C1 = setdiff(A,B,'rows') % gives 'a' to 'e'
C2 = setdiff(B,A,'rows') % gives 'u' to 'z'
C3 = setxor(A,B,'rows') % gives 'a' to 'e' and 'u' to 'z'

Separate strings and make a group from cell array

Cell_in = {'a1','b1','b3','c3','c1','d3'}; % something like this
Cell_out = {'a1','b1','c1';
'b3','c3','d3';...
}
And so on, how can this be done?
Case 1: Consistent sizes
%%// Input (different from question for a better demo)
Cell_in = {'airplane1','bat1','ball3','cat3','coal1','doggie3'};
ids = cellfun(#(x) x(end), Cell_in,'uni',0)
[~,ind] = sort(ids)
Cell_out = reshape(Cell_in(ind),[],numel(unique(ids)))' %%// Output
Output
Cell_out =
'airplane1' 'bat1' 'coal1'
'ball3' 'cat3' 'doggie3'
Case 2: Inconsistent sizes
Cell_in = {'airplane1','bat1','ball3','cat3','coal1','doggie3','cat2','ball2'};
ids = cellfun(#(x) x(end), Cell_in,'uni',0)
unique_ids_num = cellfun(#str2num,unique(ids))
ids_num = cellfun(#str2num,ids)
counts = histc(ids_num,sort(unique_ids_num))
Cell_out = cell(numel(unique_ids_num),max(counts));
for k =1:numel(counts) %%// Maybe accumarray can work here
Cell_out(k,1:counts(k)) = Cell_in(ids_num==unique_ids_num(k));
end
Output
Cell_out =
'airplane1' 'bat1' 'coal1'
'cat2' 'ball2' []
'ball3' 'cat3' 'doggie3'
Using regexp, as suggested by kyamagu, followed by accumarray to do the grouping:
[~,~,ic] = unique(cell2mat(regexp(Cell_in(:), '\d+$', 'match', 'once')));
[ic,inds] = sort(ic); % to ensure stable ordering of output
co = accumarray(ic,inds,[],#(x){Cell_in(x)});
Cell_out = vertcat(co{:});

match check in matlab

i have strings like these:
s{1,2} = 'string';
s{2,2} = 'string2';
and in workspace structure like this
U.W.string = [2 2.5 3]
I want to check (in loop) s{1,2} or s{2,2} or s{i,2} matches any structure with the same name. If so, assign values from this structure to some variable var(i). How can it be done?
Use isfields to check, if a string is the name of a field in a struct. Then use the syntax struct.(name), where name is a string to access the field. Your code might look something like:
test = struct('hello', 'world', 'count', 42, 'mean', 10);
fields = {'test', 'count';
'hello', 'text';
'more', 'less'};
values = {pi, 'dummy', -1};
for row = 1 : size(fields, 1)
for column = 1 : size(fields, 2)
if isfield(test, fields{row, column})
test.(fields{row, column}) = values{row};
end
end
end
This converts the initial struct
test =
hello: 'world'
count: 42
mean: 10
to this one
test =
hello: 'dummy'
count: 3.1416
mean: 10
A shorter implementation is achieved by removing the inner loop and giving a cell-array to isfields:
for row = 1 : size(fields, 1)
%# Note the parenthesis instead of curly braces in the next statement.
match = isfield(test, fields(row, :));
if any(match)
test.(fields{row, match}) = values{row};
end
end
Use isfield(structName,fieldName). This should do the trick:
strings{1,1} = 'foo';
strings{1,2} = 'bar';
strings{1, 3} = 'foobar';
U.W.foo = 1;
U.W.foobar = 5;
for idx = 1:length(strings)
if(isfield(U.W,strings{1,idx}))
expression = sprintf('outvar(idx) = U.W.%s',strings{1,idx});
eval(expression);
end
end

Resources