I have a sheet the the followin info
"A" "B"
_____
a 1
a 1
a 1
a 1
a 1
a 1
b 1
b 1
b 0
b 1
b 1
b 1
c 1
c 0
c 1
d 1
d 1
I Like to have an Array formula that multiplies al values on column "B" that have the same text on column "A"
I don't whant to use a pivot table, i need to solve this with formulas.
End result should be on column "C"
a = 1
b = 0
c = 0
d = 1
thanks
I can do it in two columns....
Column C formula
=IF(A3=A2,C3*B2,B2)
Column D formula
=IF(A2<>A1,CONCATENATE(A2," = ",C2),"")
gives results like this
Excel image
if the blanks are a problem,
http://www.cpearson.com/excel/NoBlanks.aspx
DPRODUCT() might do it, as well, if you can setup the criteria correctly.
OK i solved using this formula as array
=+SI(SUMA(SI((A:A=A1);B:B;0))=CONTAR.SI(A:A;A1);"OK";"")
Related
probably very simple question but yeah, dont know how of course.
I have 3 columns:
A B C
-------
5 1 A
5 2 B
5 3 C
and want to multiply column A and B, and just copy C column. All with one expresion.
So Result of multiplication A and B should be in D and result of copying should be in F:
Final result should be:
D F
---
5 A
10 B
15 C
Is there any simple method to do something like this?
this should do:
=INDEX({A1:A3*B1:B3, C1:C3})
or if you are on non-english sheet:
=INDEX({A1:A3*B1:B3\ C1:C3})
CONTEXT
I have a large number of columns with categoricals, all with different, unrankable choices. To make my life easier for analysis, I'd like to take each of them and convert it to several columns with logicals. For example:
1 GENRE
2 Pop
3 Classical
4 Jazz
...would turn into...
1 Pop Classical Jazz
2 1 0 0
3 0 1 0
4 0 0 1
PROBLEM
I've tried using ind2vec but this only works with numericals or logicals. I've also come across this but am not sure it works with categoricals. What is the right function to use in this case?
If you want to convert from a categorical vector to a logical array, you can use the unique function to generate column indices, then perform your encoding using any of the options from this related question:
% Sample data:
data = categorical({'Pop'; 'Classical'; 'Jazz'; 'Pop'; 'Pop'; 'Jazz'});
% Get unique categories and create indices:
[genre, ~, index] = unique(data)
genre =
Classical
Jazz
Pop
index =
3
1
2
3
3
2
% Create logical matrix:
mat = logical(accumarray([(1:numel(index)).' index], 1))
mat =
6×3 logical array
0 0 1
1 0 0
0 1 0
0 0 1
0 0 1
0 1 0
ind2vec do work with the cell strings, and you could call cellstr function to get such a cell string.
This codes may help (From this ,I only changed a little)
data = categorical({'Pop'; 'Classical'; 'Jazz';});
GENRE = cellstr(data); %change categorical data into cell strings
[~, loc] = ismember(GENRE, unique(GENRE));
genre = ind2vec(loc')';
Gen=full(genre);
array2table(Gen, 'VariableNames', unique(GENRE))
run such a code will return this:
ans =
Classical Jazz Pop
_________ ____ ___
0 0 1
1 0 0
0 1 0
you can call unique(GENRE) to check the categories(in cell strings). In the meanwhile, logical(Gen)(or call logical(full(genre))) contain columns with logical that you need.
P.s. categorical structure might be faster than cell string, but ind2vec function doesn't work with it. unique and accumarray might better.
I'm trying to find the largest or max value in an array/range (E44:I205) among rows with values in column D (D44:D2015) that match a word. For instance:
D E F G H I
Cheetah Cat 0 1 2 3 4
Tiger Cat 1 1 2 3 4 5
Dog 0 0 1 2 3
Among the rows with the word "*"&"cat", I want to find the max value. In this example, the formula should = 5. I've tried the following formula, but it just returns the first instance of "cat" and the associated max value in that row.
=LARGE(IF($D$25:$D$205="*"&"cat",$E$44:$I$205,),1)
Any help is much appreciated!
Use:
=AGGREGATE(14,6,E25:I205/(RIGHT(D25:D205,3)="cat"),1)
Given the values in C, I want to count how many times I encounter each of these values in the vector B. For example, if C = [1 2], I'd like to count how many "1"s are in B and how many "2"s are in B by checking the elements of array C.
However, the code I have seems to count up to 5, but what the true output should be is that the number of 1s is 2 and the number of 2s is 3.
The code I wrote is shown below. Any help would be certainly appreciated.
My code :
B = [ 1 2 1 4 5 2 2 ]
C = [ 1 2 ]
lb = length(B)
lc = length(C)
for i = 1:length(B)
for j = 1:length(C)
if B(1,i)==C(1,j)
c=c+1
A(i)=c
end
end
end
Santhan Salai gave the corrected answer if you want to stick with loops. However, for efficiency, you could achieve what you want with bsxfun and sum if you don't want to loop:
>> B = [ 1 2 1 4 5 2 2 ];
>> C = [ 1 2 ];
>> D = sum(bsxfun(#eq, B, C.'), 2)
D =
2
3
bsxfun is a nice tool that allows you to broadcast data across singleton dimensions. In our case, I used the equals functions to check for element-wise equality and I transposed C so that it becomes a column vector. What will be produced is a matrix where we have as many rows as there are in C and as many columns as there are in B. Each row of this output matrix tells you which elements were equal to each corresponding element in C. C is broadcasted such that we get a matrix of a bunch of [1;2] columns mashed together for as many elements as there are in B and B is broadcasted such that we get replicates of B with as many rows as there are in C. By doing element-wise equality, we would produce a logical matrix where each element for a row tells you which elements were equal to the corresponding value of C. All you have to do now is sum over the columns to get how many elements were equal to each value in C, hence the sum call over the second dimension.
If you want overkill, you can also use accumarray. Assuming that B and C only consist of integers, do:
>> B = [ 1 2 1 4 5 2 2 ];
>> C = [ 1 2 ];
>> D = accumarray(B.', 1);
D =
2
3
0
1
1
This however computes the frequency of all unique values in B, and so you'd just want the first two entries in D.
One more alternative is to use histc:
>> B = [ 1 2 1 4 5 2 2 ];
>> C = [ 1 2 ];
>> D = histc(B, C)
D =
2 3
What you are basically computing is a histogram of B at specified bins, which are denoted at C.
Using arrayfun could be one alternate to your loop
out = arrayfun(#(x) sum(ismember(B,x)), C)
Here is your corrected loop
count = zeros(1,numel(C));
for ii = 1:numel(C)
for jj = 1:numel(B)
if (C(ii) == B(jj))
count(ii) = count(ii) + 1;
end
end
end
I have 3 columns that follow these rules:
Any cell in Col A may be empty, otherwise it contains a string.
If a row in Col A is empty, that row in Col's B and C will be empty.
If a row in Col A is populated, That row in Col B will be populated with an integer, and that row in Col C may be empty or have a "1".
I need a script that, for each cell in Col A,
Checks the string in that cell and looks for all identical strings in Col A.
For each row containing said matching string, checks Col C for a "1"
For each row where both of the above are true, sum the values in Col B and replace each of them with that sum.
So for example, this:
A B C
x 1
x 2
z 2 1
y 1 1
y 2 1
y 1
z 2 1
z 1 1
Should become this:
A B C
x 1
x 2
z 5 1
y 3 1
y 3 1
y 1
z 5 1
z 5 1
So 3 different strings are found in Col A, (x y and z). Duplicates of x are found but the values in col B are not summed because there was no "1" in Col C. Dupes of y are found, but only those with a "1" to the right are summed. All dupes of z found have a "1", so all are summed.
What's the best way to do this? Please let me know if I need to clarify something about this question (I know it's convoluted, but I spent a lot of time trying to make it as clear as possible haha).
A simple formula should do the job : assuming the data are found in A:C
=IF(ISBLANK(A2),"",IF(ISBLANK(C2),B2, SUMIFS(B:B,A:A,A2,C:C,1)))
The outer IF display nothing when column A is empty.
The inner IF displaycolumn B when column C is empty.
The SUMIFS will add upcolumn B where column A is the same(as current row) and when column C is 1.