Generating an array using absolute values instead of cell references - arrays

This question is related to this one
I have (3,0), (2,1), and (2,0) in rows 1 to 3. There are ways to generate the array of {0,0,0,1,1,0,0} using cell addresses. (See the reference above.)
Now, my question is can the same array be generated NOT using the cell references but using the three pairs of the numbers only?
NOTE: In the real case, there may be up to six pairs of numbers, A1:B1 to A6:B6, and up to 2880 array elements.
Excel 2010
A B
1 3 0
2 2 1
3 2 0

You can proceed as in the edit to my answer to the original question, by generating an array as follows:
0 0 0
1 0 0
1 1 0
and using Mmult instead of Offset to get the running totals of the first column of numbers.
=SUM(INDEX(INDEX({3,0;2,1;2,0},0,2),N(IF({1},MATCH(ROW(A1:INDEX(A:A,SUM(INDEX({3,0;2,1;2,0},0,1)))),
MMULT(IF(ROW(A1:INDEX($1:$1048576,COUNT(INDEX({3,0;2,1;2,0},0,1)),COUNT(INDEX({3,0;2,1;2,0},0,1))))>
COLUMN(A1:INDEX($1:$1048576,COUNT(INDEX({3,0;2,1;2,0},0,1)),COUNT(INDEX({3,0;2,1;2,0},0,1)))),1,0),INDEX({3,0;2,1;2,0},0,1))+1)))))
If you hard-code the number of pairs of numbers instead of using Countif to count them, the formula is shorter:
=SUM(INDEX(INDEX({3,0;2,1;2,0},0,2),N(IF({1},MATCH(ROW(A1:INDEX(A:A,SUM(INDEX({3,0;2,1;2,0},0,1)))),
MMULT(IF(ROW(A1:INDEX($1:$1048576,3,3))>
COLUMN(A1:INDEX($1:$1048576,3,3)),1,0),INDEX({3,0;2,1;2,0},0,1))+1)))))

Related

how to use countif with array excel 2016?

In an excel spreadsheet I have multiple sites with 2 rows of data for each site (A, B). There are 25 observations (columns 1 - 5) for each site. I would like to count the number of cases for each site where A + B > 0.
For example,
Site1 A 0 0 1 2 0
Site1 B 1 0 1 0 0
the count would be 3 (that is A+B >0 for 3 cases in site 1). I could add a third line for each site to get the sum and then count the number of cells > 0, but I am not interested in adding an additional line for each site. I have not found an array formula that works for this situation.
=SUM(--((C1:G1+C2:G2)>0))
This is an array formula.
In older versions of Excel, you can use:
=SUMPRODUCT(--((C1:G1+C2:G2)>0))
Or you can enter the original as an array formula
To enter/confirm an array formula, hold down ctrl + shift while hitting enter. If you do this correctly, Excel will place braces {...} around the formula seen in the formula bar.

Merge multiple arrays of unique occurrences

I want to merge multiple arrays of unique occurrences to a single array. To get the arrays in the first place I use this code, where image series is a slice from a tiff image imported using imread:
a = unique(img_series);
occu = [a,histc(img_series(:),a)];
I do that multiple times, because the tiff image I'm using has multiple hundred images stacked, which my RAM will not support to import at once. So each 'occu' looks something like this (first number is the unique value, second number is the number of occurrences):
occu1 occu2 .....
0 1 1 2
12 1 10 1
14 1 12 1
15 1 14 2
.. .. .. .. .....
Now I want to merge them all together, or better merge them in each iteration, when I'm reading another stacked image.
The merged results should be a 2D matrix similar to the one above. The number of occurrences of the same values should be added to one another, as this is the whole point of counting them. So the result of the above example should be this:
occu_total
0 1
1 2
10 1
12 2
14 3
15 1
.. ..
I found the join command, but that one does not seem to work here. I guess I could do it the long way of searching the matching number and add the occurrences together and so on, but there must be a quicker way of doing it.
A = [0 1;12 1; 14 1;15 1];B = [1 2;10 1;12 1;14 2];
tmp = [A;B]; %// merge arrays into a single one
tmp(:,1) = tmp(:,1)+1;%// remove zero occurrences by adding 1 to everything
C = accumarray(tmp(:,1),tmp(:,2)); %// add occurrences all up
D = [1:numel(C)].'; %// create numbered array
E = [D C];
E((C==0),:)=[]; %// get output
E(:,1) = E(:,1)-1;%// subtract the 1 again
E =
0 1
1 2
10 1
12 2
14 3
15 1
Job for accumarray. This takes the first argument as your dictionary key, and adds the values of the each key together. The addition and subtraction of 1 is done because 0 cannot be an index in MATLAB. To circumvent this (assuming you have no negative numbers), you can simply add 1 and remove that afterwards, shifting all your indices to positive integers. If you hit negative numbers, subtract tmp(:,1) = min(tmp(:,1)+1 and add E(:,1) = min(tmp(:,1)-1

Picking out elements of an array according to a specific rule

So I have a 100000-by-2 matrix in MATLAB. I want to extract only the elements in the second column which all have the same element for their corresponding row in the first column. E.g. if we have:
A = [1 2
3 4
2 6
1 5
4 1
1 3]
and then specify that we want all elements in the second column with 1 as their corresponding value in the 1st column. So I would want the above to become:
2
5
3
Does anyone know how to do this in MATLAB?
Matlab supports matrix operations, so you can do what you want without having to explicitly loop through the entire matrix like some other languages.
By using logical indexing, (more on that here https://www.mathworks.com/help/matlab/math/matrix-indexing.html?refresh=true)
you can extract the necessary elements from your matrix.
First you want to create a [0,1] array of rows in your matrix that satisfy your condition.
You can do that with
A(:,1) == 1
This will produce
1
0
0
1
0
1
Which means that the first, fourth and last rows satisfy the condition where the element in the first column of the matrix satisfies the condition that it equals one.
Now you can use this to produce the elements in the second column, by simply using it as an index of your original matrix.
A(A(:,1)==1,2)
to produce the required result.

Look at each row separately in a matrix (Matlab)

I have a matrix in Matlab(2012) with 3 columns and X number of rows, X is defined by the user, so varies each time. For this example though I will use a fixed 5x3 matrix.
So I would like to perform an iterative function on each row within the matrix, while the value in the third column is below a certain value. Then store the new values within the same matrix, so overwrite the original values.
The code below is a simplified version of the problem.
M=[-2 -5 -3 -2 -4]; %Vector containing random values
Vf_X=M+1; %Defining the first column of the matrix
Vf_Y=M+2; %Defining the secound column of the matrix
Vf_Z=M; %Defining the third column of the matrix
Vf=[Vf_X',Vf_Y',Vf_Z']; %Creating the matrix
while Vf(:,3)<0
Vf=Vf+1;
end
disp(Vf)
The result I get is
1 2 0
-2 -1 -3
0 1 -1
1 2 0
-1 0 -2
Ideally I would like to get this result instead
1 2 0
1 2 0
1 2 0
1 2 0
1 2 0
The while will not start if any value is above zero to begin with and stops as soon as one value goes above zero.
I hope this makes sense and I have supplied enough information
Thank you for your time and help.
Your current problem is that you stop iterating the very moment any of the values in the third row break the condition. Correct me if I'm wrong, but what I think you want is to continue doing iterations on the remaining rows, until the conditions are broken by all third columns.
You could do that like this:
inds = true(size(Vf,1),1);
while any(inds)
Vf(inds,:) = Vf(inds,:)+1;
inds = Vf(:,3) < 0;
end
Of course, for the simple addition you provide, there is a better and faster way:
inds = Vf(:,3)<0;
Vf(inds,:) = bsxfun(#minus, Vf(inds,:), Vf(inds,3));
But for general functions, the while above will do the trick.

an array of arrays varied in length in R

I use R for my statistical analysis.
I wanna group my data in an array based on the ID column. This results in having an array of unique IDs which each cell includes a data array of correspondence ID. Since the number of the data per ID is not similar, therefor each array in each cell has different length.
So I wonder how I can create an array of arrays varied in length using R?
I already having the following codes but get an error:
#number of unique IDs
size<-unique(data[,1]);
for (i in 1:length (gr))
{
index<- which(data[,1]==gr[i]);
data_c[[i,1]]<-data[index,];
}
Here is the error
more elements supplied than there are to replace
Thanks in advance for any comment.
I explain my problem by an example:
I have following data called it DATA_ALL:
DATA_ALL[]=
id age T1 T2 T3 T4
1 20 1 0 0 0
1 20 NA 0 NA 0
1 20 0 0 0 0
5 30 1 NA 0 0
5 30 0 0 0 1
6 40 0 1 0 0
I want to group the data of each id and put all in an array (array of arrays):
DATA_GROUPED []=
id data
1 1 X1[]=[an array includes all data from DATA_ALL where the id=1]
2 5 X2[]=[an array includes all data from DATA_ALL where the id=5]
3 6 X3[]=[an array includes all data from DATA_ALL where the id=6]
Please note that the length of X1!=X2!=X3
So how I can create the DATA_GROUPED[] matrix??
It is nearly impossible to answer your question in relation to your code, but in general, I think what you want to do is create a list of vectors, a bit like this:
one<-letters[1]
two<-letters[2:3]
three<-letters[4:6]
combined<-list(one=one, two=two, three=three)
Be sure to use indexing correctly now, and preferably with [[:
for(i in 1:length(combined))
{
cat("The contents of item", names(combined)[i], "are:", combined[[i]], "\n")
}
Output:
The contents of item one are: a
The contents of item two are: b c
The contents of item three are: d e f
Edit (following edit of question):
split.data.frame(DATA_ALL, DATA_ALL[,1])
Check ?split and note the first paragraph in Details.
Note this indeed creates a list of matrices/arrays.

Resources