How to iteratively apply a function to groups of data in Excel - excel

So I'm quite new to using excel and it's possible I missed over a question like this that was already answered, but what I am trying to do is measure the distances between groups of points in a large excel sheet.
I've tried the standard way of writing a function and dragging it down but the way the function changes when I move it down is not what I need and I can't seem to figure how how I might fix this so I think a macro might be the solution.
The data is groups of 8 measurements with every group having one Blue, Red, Yellow, Csome, Overlap, Green, Cyan, and Full object. The XYZ coordinate of each object is listed in the first three columns and using a simple distance formula I am trying to measure the distance between each object and all the other objects in it's same group. Eg. Blue to Red, Yellow, Csome... etc. Then again for Blue2 to Red2, Yellow2, Csome2... and Blue3 to Red3, Yellow3, Csome3... and so fourth.
However, when I put the following formula in where my desired output should be and try to drag it down, obviously I run into some problems. For the first Blue against it's whole group, I begin with =SQRT((A$2-A2)^2+(B$2-B2)^2+(B$2-B2)^2) and drag it down so it cycles through row 2 versus rows 3,4,5,6,7,8,and 9. The issue arises when I get to row 10 which contains Blue2. This should not be compared with Blue1 but rather begins a new group. How then can I get the cycle to restart at row 10 so that the new group beginning with Blue 2 is compared within that group, eg the XYZ in row 10 to XYZ in 11, 12, 13...
:
Position X Position Y Position Z Unit Category Collection Surpass Object
16.38 41.20 4436.18 um Surface Position Blue Selection
17.35 40.83 4436.17 um Surface Position Red Selection
15.93 40.62 4435.93 um Surface Position Yellow Selection
16.22 40.80 4436.03 um Surface Position Csome1
17.97 42.23 4435.46 um Surface Position Overlap
15.37 40.87 4436.03 um Surface Position Green Selection
15.44 40.04 4436.39 um Surface Position Cyan Selection
17.97 42.23 4435.46 um Surface Position Full 1
15.57 36.20 4435.75 um Surface Position Blue Selection 2
12.83 35.19 4435.33 um Surface Position Red Selection 2
15.76 37.25 4435.74 um Surface Position Yellow Selection 2
14.94 36.17 4435.65 um Surface Position Csome2
15.99 36.78 4436.34 um Surface Position Overlap 2
14.23 36.26 4435.57 um Surface Position Green Selection 2
13.61 36.96 4436.09 um Surface Position Cyan Selection 2
14.64 36.42 4435.80 um Surface Position Full 2
42.83 36.04 4435.47 um Surface Position Blue Selection 3
42.34 36.56 4435.63 um Surface Position Red Selection 3
42.25 36.87 4435.75 um Surface Position Yellow Selection 3
42.48 36.50 4435.62 um Surface Position Csome3
41.77 36.02 4435.67 um Surface Position Overlap 3
42.64 36.89 4435.73 um Surface Position Green 3
42.05 36.90 4436.21 um Surface Position Cyan Selection 3
42.34 36.53 4435.71 um Surface Position Full 3
33.75 33.13 4436.32 um Surface Position Blue Selection 4
34.99 33.12 4436.38 um Surface Position Red Selection 4
35.40 31.97 4436.38 um Surface Position Yellow Selection 4
34.75 32.58 4436.36 um Surface Position Csome4
39.03 35.24 4436.04 um Surface Position Overlap Selection 4
35.49 32.19 4436.49 um Surface Position Green Selection 4
36.14 32.35 4436.42 um Surface Position Cyan Selection 4
36.16 33.20 4436.30 um Surface Position Full 4

Applying some VBA to loop through the matches to Full with a wildcard and reset the formula's starting row for each iteration should be the best way to go with this.
Sub Group_Formula()
Dim frmla As String, rw As Long, rws As Long, n As Long, cnt As Long
frmla = "=SQRT((A$×-A×)^2+(B$×-B×)^2+(B$×-B×)^2)"
With ActiveSheet '<-set to worksheet name properly!
For cnt = 1 To Application.CountIf(.Columns("G"), "Full*")
rw = Application.Max(2, rw)
rws = Application.Match("Full*", .Cells(rw, "G").Resize(Rows.Count - rw, 1), 0)
.Cells(rw, "H").Resize(rws, 1).Formula = Replace(frmla, Chr(215), rw)
rw = rw + rws
Next cnt
End With
End Sub
The results should resemble the following.
    

You need to handle the A$2, B$2 references with a function that will calculate the row. You can use reference functions like INDEX, INDIRECTor OFFSET to accomplish what you need. The last two are volatile, so keep in mind they recalculate every time a value changes in your sheet. INDEX is more efficient.
It isn't clear if your data includes the group number because the numbers at the end of the row are inconsistent. If they are consistent in your data you can use them. Supposing the group number is in column I, This INDEX formula will return the correct A$2 reference:
INDEX($A$2:$A$33,1+((I2-1)*8))
Or with the OFFSET function:
OFFSET($A$2,(I2-1)*8,0)
Otherwise, (without using the group number) you can use the ROWS function to produce a similar result:
INDEX($A$2:$A$33,1+QUOTIENT(ROWS(A$2:A2)-1,8)*8)
The 8 in all the formulas represent the number of items in a group.
And the full formula would be:
=SQRT((INDEX($A$2:$A$33,1+QUOTIENT(ROWS(A$2:A2)-1,8)*8)-A2)^2+(INDEX($B$2:$B$33,1+QUOTIENT(ROWS(B$2:B2)-1,8)*8)-B2)^2+(INDEX($C$2:$C$33,1+QUOTIENT(ROWS(C$2:C2)-1,8)*8)-C2)^2)

Well as a new excel user you've jumped straight into the wonderful and perplexing world of array formula's.
First you need to prep your data a bit. All those 1s, 2s, 3s and 4s need to be in a column of their own, all those in group 1 need a number, and everything needs to be named consistently ('Green' vs 'Green Selection'). We could make the formula even more complex to account for these idiosyncracies in your data, but cleaning it will make understanding it and the formulas easier.
Now we put the "Surpass Object" we want to calculate the distance from in Cell I1 (in this case 'Blue Selection') and the following formula into cell I2 being sure to hold ctrl+shift+enter when we enter it.
=SQRT((INDEX($A$2:$A$33,MATCH(1,($G$2:$G$33=I$1)*($H$2:$H$33=$H2),0))-$A2)^2+(INDEX($B$2:$B$33,MATCH(1,($G$2:$G$33=I$1)*($H$2:$H$33=$H2),0))-$B2)^2)
This will get us the distance between the x and y co-ordinates for each. You'll need to adjust the formula to add the z-coordinate to the calculation if you need it.
So what is the fancy index-match formula doing? In the first instance it grabs the cell in column a, that matches both the 'Surpass Object' in the column header (cell J$1) and the group of the current row (cell $H2)
Now you can just fill in the remaining headers and fill the formula right and down to get your matrices of differences

Related

Excel charts are placed on different positions depending on screen resolution

I am creating some charts with VBA. Target is to position them at the upper left corner of a cell (here as range rgCht) with a size of 16 rows x 9 columns.
Here is the code:
' Calculate active cell to place the chart
Set rgCht = wsGr.Cells(i * 17 + 2, 2)
Set cht = wsGr.ChartObjects.Add( _
Left:=rgCht.Left, _
Width:=rgCht.Width * 9, _
Top:=rgCht.Top, _
Height:=rgCht.Height * 16)
The result is that if the sheet is displayed on my notebook screen while the macro runs, all charts are placed and sized properly. However when I run it on a bigger screen, the charts are shifted 1 unit per row down, i. e. in line 70 I have 7 units difference between the calculated position and the real position on the sheet:
The line height is 14.5 units, so in row 70 the top position is 1000.5 . However when I manually move the chart to the top left corner of the cell and check the coordinates, I get 993.5.
I'm running out of ideas. Any hint is appreciated.
Both monitors run with a resolution of 1920x1080. Only difference is that the scaling is 125% on the big screen and 150% on the small one.

wordcloud2 drops long words, which gets the colors mismatched

so i have a dynamic list of text that i want to visualize in a wordcloud. sometimes some of the words are too long and they get dropped from the display. i can scale down the size of everything, but it's not always clear what scale i should get down to in order to prevent things from being dropped. i'd rather not fiddle with this and just accept some things are dropped. also, everything is in a shiny app and i have a slider to control scale if really needed. the problem though is i want my text colored by properties of the words in my dataset. in this example below you can see how each "word" has a color associated with it...
wc <- data.frame(
word = c("too big to fit this one is","red","green","blue"),
freq = c(2,1,2,3),
col = c("black","red","green","blue"),
stringsAsFactors = FALSE
)
>wc
word freq col
1 too big to fit this one is 2 black
2 red 1 red
3 green 2 green
4 blue 3 blue
wordcloud2(wc, color = wc$col)
this then draws the wordcloud but the first element is dropped and the colors don't drop too ("red" is colored black, "green" is colored red, and "blue" is colored green). i can't do wordcloud2(wc, color = col) like an aes style call in ggplot, the wordcloud does draw but all the text is clear... i can hover over it but not see any of it. anyone else work through this issue? thanks!!!

Use Excel/VB to create a list of product variations based parent products

I am creating a shopify store and I have 3 product variations i.e. size/colour/customisation location which I need to split to create a line for each potential variant.
An example of my sheet is included below. I can provide the excel if easier.
I hope I am explaining correctly.
I am hoping to achieve for the first example, the tshirt would have a Small option, in black with the customisation location left breast
then next line would have Small option, in black with the customisation location right breast and so on.
I am a novice so any help would be appreciated
You need 3 nested loops for that.
Here is an example
Option Explicit
Public Sub ExampleGenerateUniquePermutations()
Dim ArraySize() As Variant
ArraySize = Array("S", "M", "L")
Dim ArrayColor() As Variant
ArrayColor = Array("red", "green")
Dim ArrayVariation() As Variant
ArrayVariation = Array("left", "right", "extra", "nonsense")
Dim Size As Variant
For Each Size In ArraySize
Dim Color As Variant
For Each Color In ArrayColor
Dim Variation As Variant
For Each Variation In ArrayVariation
Debug.Print Size, Color, Variation
Next Variation
Next Color
Next Size
End Sub
The output will be
S red left
S red right
S red extra
S red nonsense
S green left
S green right
S green extra
S green nonsense
M red left
M red right
M red extra
M red nonsense
M green left
M green right
M green extra
M green nonsense
L red left
L red right
L red extra
L red nonsense
L green left
L green right
L green extra
L green nonsense
Note that you can easily split your string "S;M;L;XL" into an array using the split function ArraySize = Split("S;M;L;XL", ";")

Syntax to set color of LED in sense-hat using nodered

I am working on sense-hat using node-red. I found that, to set the four corners of the display to red, green (#00ff00), yellow and blue (0,0,255):
0,0,red,0,7,#00ff00,7,7,yellow,7,0,0,0,255
But how to set color for 2 leds in column 2 and 3 of the LED panel in rows 2-7.
Can anyone please suggest me in this?
The sidebar help for the SenseHAT node describes the required syntax:
Format: <x>,<y>,<colour>
x and y must either be a value from 0 to 7,
a * to indicate the entire row or column,
or a range such as 3-6.
But how to set color for 2 leds in column 2 and 3 of the LED panel in rows 2-7.
If you want to set just two leds within those ranges then just pick two X/Y values within that range and set them.
2,2,red,2,3,red

How to avoid "A Chart may only have up to 256 series" issue (Excel VBA)

I'm trying to build bubble chart from a scratch in excel. Below is piece of code I'm using. Everything works fine until SeriesCollection.NewSeries reaches 256. Then I'm getting error message: A Chart may only have up to 256 series.
Can you anybody help me, how to avoid this issue. Is there any more elegant solution? Thanks a lot for any of your hint or advice.
Source code for my bubble chart:
With wsAnalytics.ChartObjects.Add(Left:=0, Width:=995, Top:=0, Height:=580)
For i = 1 To Range("Config_BubbleChartData").Rows.Count
.Chart.SeriesCollection.NewSeries
.Chart.SeriesCollection(i).name = Range("Config_BubbleChartData").Rows(i).Cells(1, 1)
.Chart.SeriesCollection(i).XValues = Range("Config_BubbleChartData").Rows(i).Cells(1, 3)
.Chart.SeriesCollection(i).Values = Range("Config_BubbleChartData").Rows(i).Cells(1, 4)
Select Case BubbleColor
Case 1
.Chart.SeriesCollection(i).Format.Fill.ForeColor.RGB = RGB(255, 0, 0)
Case 2
.Chart.SeriesCollection(i).Format.Fill.ForeColor.RGB = RGB(0, 0, 255)
Case 3
.Chart.SeriesCollection(i).Format.Fill.ForeColor.RGB = RGB(0, 255, 0)
End Select
If i = 1 Then .Chart.ChartType = xlBubble3DEffect
.Chart.SeriesCollection(i).BubbleSizes = "=" & Range("Config_BubbleChartData").Parent.name _
& "!" & Range("Config_BubbleChartData").Rows(i).Cells(1, 5).Address(1, 1, xlR1C1)
Next i
You only need as many series as you have colors. Certainly you don't need more than 255 colors, since no human would be able to distinguish more than a dozen in a cluttered bubble chart.
Set up the data with four columns for X, Y, bubble size, and bubble color. Append another column for each color in the bubble color column, and use the color name as the column header. Use an IF formula in these columns to put the Y value for each color into the appropriate column.
In my example, I have X and Y in columns A and B, bubble size and color in C and D, plus the bubble color names in E1:G1. The formula in cell E2 is
=IF($D2=E$1,$B2,NA())
and I've filled this into E2:G16. The result is the Y value if the column header matches the color, and #N/A otherwise, which will not plot.
Select A2:C19 and create the bubble chart (top left chart).
Click the Select Data button on the Chart Tools > Design tab of the ribbon, select the only series in the chart, and Edit it, so cell E1 is used for the name, and E2:E16 is used for the Y values. Keep A2:A16 as the X values and C2:C16 as the bubble size. This series will have the default color for the first series, which in Excel 2013 and 2016 is blue (top right chart).
Stay in or return to the Edit Data dialog, and add a series. Use cell F1 for series name, A2:A16 as X values, F2:F16 as Y values, and C2:C16 as the bubble size. This series will use the default second color, orange (bottom left chart).
Add one more series, use cell G1 for series name, A2:A16 as X values, G2:G16 as Y values, and C2:C16 as the bubble size. This series uses the default third color, gray (bottom right chart).
Note that all series use the same X values and bubble sizes, but different Y values.

Resources