I would like to implement the following function:
Input:
Vector of values
Vector of the same size, stating the number of occurrences each value (of the corresponding index) should have in the output vector.
Output:
A vector of the values, 1by1 in repeating sequences, where each value appears as it's needed number of occurrences.
The values will continue appearing 1by1, untill a value appeared as many times as needed, then the rest of the values will continue appearing without it.
Example:
Inputs:
[1,2,3,4]
[3,2,5,1]
Output: [1 2 3 4 1 2 3 1 3 3 3]
Wanted Solution:
I would like to find a solution that is simple, but does not use any loops, and is modular to any length of the input vectors.
Current Solution:
So far only managed to implement with loops or with unpleasant indexing. The solution with loops is as follows:
Double Loop:
vals_vec=1:4;
occur_vec=[3,2,5,1];
output_vec=zeros(1,sum(occur_vec));
num_of_vals=length(vals_vec);
output_i=1;
while (output_i<=length(output_vec)) % While in length of output vector
for cur_val_i=1:num_of_vals % Loop over all values
if(occur_vec(cur_val_i)>0) % If value hasn't reached its occurrence number
occur_vec(cur_val_i)=occur_vec(cur_val_i)-1;
output_vec(output_i)=vals_vec(cur_val_i);
output_i=output_i+1;
end
end
end
output_vec
Single Loop:
vals_vec=1:4;
occur_vec=[3,2,5,1];
output_vec=[];
for cur_num_of_vals=length(vals_vec):-1:1
[min_val,min_i]=min(occur_vec); % Find lowest occurrence number
output_vec=[output_vec,repmat(vals_vec,1,min_val)]; % Add vals accordingly
vals_vec=[vals_vec(1:min_i-1),vals_vec(min_i+1:cur_num_of_vals)]; % Remove the corresponding val
occur_vec=occur_vec-min_val; % Reduce Occurences from all vals
occur_vec=[occur_vec(1:min_i-1),occur_vec(min_i+1:cur_num_of_vals)]; % Remove the corresponding occurrence number
end
output_vec
Thanks!
There are two methods to create a vector with repeated values in R but both of them have different approaches, first one is by repeating each element of the vector and the second repeats the elements by a specified number of times. Both of these methods use rep function to create the vectors.
The rep function creates a vector with repeated elements.
u = repelem( v , n ) , where v is a scalar or vector, returns a vector of repeated elements of v . If n is a scalar, then each element of v is repeated n times. The length of u is length(v)*n .
How do you Repeat a Sequence of Numbers in R? To repeat a sequence of numbers in R you can use the rep() function. For example, if you type rep(1:5, times=5) you will get a vector with the sequence 1 to 5 repeated 5 times.
You can do this by over-replicating the input, then removing surplus repetitions.
Edit: here is a solution with no looping:
% Repeat array to max number of possible repetitions
out = repmat( vals, 1, max(reps) );
% Implicit expansion (requires R2016b or newer, otherwise use bsxfun) to create
% matrix of reducing repetition count, then remove repeated values
% where this is <= 0, i.e. where there are no repetitions remaining.
out(reshape( reps' - (0:max(reps)-1), 1, [] ) <= 0) = [];
% Pre-R2016b version would be
% out(reshape( bsxfun(@minus, reps', (0:max(reps)-1)), 1, [] ) <= 0) = [];
Original: Requires a single loop, but over the input values not the output array so it's at least a short one...
vals = [1,2,3,4];
reps = [3,2,5,1];
out = repmat( vals, 1, max(reps) ); % repeat array to max number of possible repetitions
for ii = 1:numel(vals)
% Remove elements which have appeared too many times
out( out == vals(ii) & (cumsum(out==vals(ii)) > reps(ii)) ) = [];
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With