Swapping the duplicates in Column - columnsorting

I need some help to determine the best approach on how I can use VBA to find duplicates in a column 2 and swap the rows that have the duplicates in Column 2 (in this example the row 5 with row 6). Please see below sample.
Column 1 Column 2 Column 3
A 1 yes
B 2 no
C 3 no
D 4 yes
E 5 no
F 5 yes

Related

Sorting/ordering values from smallest to biggest in an array

I have a formula like this : =ArrayFormula(sort(INDEX($B$1:$B$10,MATCH(E1,$A$1:$A$10,0))))
in columns A:B:
a 1
b 2
c 3
d 4
e 5
f 6
g 7
h 8
i 9
j 10
and
the data to convert in E:H
a c f e
f a c b
b a c d
I get the following results using the above formula
in columns L:O:
1 3 6 5
6 1 3 2
2 1 3 4
My desired output is like this:
1 3 5 6
1 2 3 6
1 2 3 4
I'd like to arrange the numbers from smallest to biggest in value. I can do this with additional helper cells. but if possible i'd like to get the same result without any additional cells. can i get a little help please? thanks.
To sort by row, use SORT BYROW. But unfortunately, nested array results aren't supported in BYROW. So, we need to JOIN and SPLIT the resulting array.
=ARRAYFORMULA(SPLIT(BYROW(your_formula,LAMBDA(row,JOIN("🌆",SORT(TRANSPOSE(row))))),"🌆"))
Here's another way using Makearray with Index to get the current row and Small to get the smallest, next smallest etc. within the row:
=ArrayFormula(makearray(3,4,lambda(r,c,small(index(vlookup(E1:H3,A1:B10,2,false),r,0),c))))
Or you could change the order (might be a little faster) as you don't need to vlookup the entire array, just the current row:
=ArrayFormula(makearray(3,4,lambda(r,c,small(vlookup(index(E1:H3,r,0),A1:B10,2,false),c))))
It's interesting (to me at any rate) that you can interrogate the row and column number of the current cell using Map or Scan, so this is also possible:
=ArrayFormula(map(E1:H3,lambda(cell,small(vlookup(index(E1:H3,row(cell),0),A1:B10,2,false),column(cell)-column(E:E)+1))))
Thanks to #JvdV for this insight (which may be obvious to some but wasn't to me) shown here in Excel.
try:
=INDEX(TRIM(SPLIT(FLATTEN(QUERY(QUERY(QUERY(SPLIT(FLATTEN(E1:H3&"×​"&ROW(E1:H3)), "​"),
"select max(Col1) group by Col1 pivot Col2"), "offset 1", 0),,9^9)), "×")))
or if you want numbers:
=INDEX(IFNA(VLOOKUP(TRIM(SPLIT(FLATTEN(QUERY(QUERY(QUERY(SPLIT(FLATTEN(E1:H3&"×​"&ROW(E1:H3)), "​"),
"select max(Col1) group by Col1 pivot Col2"), "offset 1", 0),,9^9)), "×")), A:B, 2, 0)))

Best approach for formula of matching values in sheet 2

I need to populate column A in sheet two based on multiple columns in sheet one.
For example, here are two of multiple conditions:
If columns A,B,C,D (of sheet 2) are all 5/6 then populate corresponding row in sheet one with "mid".
If columns A,B,C,D (of sheet 2) contain at least one 3 and L,M,O contain all 0s, populate "low".
I believe using SWITCH would make the most sense, unless someone can reccommend a simpler approach?
My main issue is with the syntax of writing this, I am getting a formula parse error:
=SWITCH(Sheet 1!G2:G&K2:K,ISBETWEEN(5,6),"mid")
Sheet 1
A B C D E F G H I J K L M N O
2 2 3 2 0 0 0 0
5 5 6 6
In row one of my example sheet 2 would get "mid" and row 2 would get "low"
try:
=ARRAYFORMULA(
IF( 4=LEN(REGEXREPLACE(FLATTEN(QUERY(TRANSPOSE(A1:D5),,9^9)), "[^5-6]+", )), "mid",
IF((4=LEN(REGEXREPLACE(FLATTEN(QUERY(TRANSPOSE(L1:O5),,9^9)), "[^0]+", )))*(REGEXMATCH(FLATTEN(QUERY(TRANSPOSE(A1:D5),,9^9)), "3")), "low", )))

Increase the numbers in apl

I have the following data:
a b c d
5 9 6 0
3 1 3 2
Characters in the first row, numbers in the second row.
How do I get the character corresponding to the highest number in the second row, and how do I increase the corresponding number in the second row? (For example, here, column b has the highest number, 9, so increase that number by 10%.)
I use Dyalog version 17.1.
With:
⎕←data←3 4⍴'a' 'b' 'c' 'd' 5 9 6 0 3 1 3 2
a b c d
5 9 6 0
3 1 3 2
You can extract the second row with:
2⌷data
5 9 6 0
Now grade it descending, that is, find the indices that would sort it from highest to lowest:
⍒2⌷data
2 3 1 4
The first number is the column we're looking for:
⊃⍒2⌷data
2
Now we can use this to extract the character from the first row:
data[⊂1,⊃⍒2⌷data]
b
But we only need the column index, not the actual character. The full index of the number we want to increase is:
2,⊃⍒2⌷data
2 2
Extracting the data to see that we got the right index:
data[⊂2,⊃⍒2⌷data]
9
Now we can either create a new array with the target value increased by 10%:
1.1×#(⊂2,⊃⍒2⌷data)⊢data
a b c d
5 9.9 6 0
3 1 3 2
Or change it in-place:
data[⊂2,⊃⍒2⌷data]×←1.1
data
a b c d
5 9.9 6 0
3 1 3 2
Try it online!

SAS grouping algorithm

I have the following mock up table
#n a b group
1 1 1 1
2 1 2 1
3 2 2 1
4 2 3 1
5 3 4 2
6 3 5 2
7 4 5 2
I am using SAS for this problem. In column group, the rows that are interconnected through a and b are grouped. I will try to explain why these rows are in the same group
row 1 to 2 are in group 2 since they both have a = 1
row 3 is in group 2 since b = 2 in row 2 and 3 and row 2 is in group 1
row 3 and 4 are in group 1 since a = 2 in both rows and row 3 is in group 1
The overall logic is that if a row x contains the same value of a or b as row y, row x also belongs to the same group as y is a part of.
Following the same logic, row 5,6 and 7 are in group 2.
Is there any way to make an algorithm to find these groups?
Case I:
Grouping defined as to be item linkage within contiguous rows.
Use the LAG function to examine both variables prior values. Increase the group value if both have changed. For example
group + ( a ne lag(a) and b ne lag(b) );
Case II:
Grouping determined from pair item slot value linkages over all data.
From grouping pairs by either key
General statement of problem:
-----------------------------
Given: P = p{i} = (p{i,1},p{i,2}), a set of pairs (key1, key2).
Find: The distinct groups, G = g{x}, of P,
such that each pair p in a group g has this property:
key1 matches key1 of any other pair in g.
-or-
key2 matches key2 of any other pair in g.
Demonstrates
… an iterative way using hashes.
Two hashes maintain the groupId assigned to each key value.
Two additional hashes are used to maintain group mapping paths.
When the data can be passed without causing a mapping, then the groups have
been fully determined.
A final pass is done, at which point the groupIds are assigned to each
pair and the data is output to a table.

Natural Join of different tables

Could you please explain to me how to do a NATURAL JOIN on these two relations (one having 5 and the other one 3 rows?
1st relation
A C
3 3
6 4
2 3
3 5
7 1
2nd relation
B C D
5 1 6
1 5 8
4 3 9
In your question you have two separate relations, which have one attribute (i.e. column) in common: C.
A natural join will combine all tuples in both relations with that attribute in common. You will end up with the results:
A B C D
7 5 1 6
3 4 3 9
2 4 3 9
3 1 5 8
This can be performed in SQL by using the code #Matthew posted.
Something like:
SELECT * FROM 1stRelation NATURAL JOIN 2ndReleation
It will do the same thing and an inner join using the explicit column names. I.e.:
SELECT * from 1stRelation as x INNER JOIN 2ndRelation as z ON x.C=z.C
Personally - I prefer not to use them except in the possible case where I am not aware of the table structure in advance but know they should be able to be joined.
Basicly you do a CROSS JOIN, i. e. you combine every row from the 1st relation with every row of the 2nd relation. Then you have two C columns. Now you eliminate every row where the two C are not equal and merge them as only one column C.

Resources