Calculate values between two numbers (Google Sheets) - arrays

If 15 is the lowest number and 200 the highest number, what formula do I need to use to define a multiplication pattern that applies the 28 values needed to complete this multiplication table?
I would like to learn how to create this pattern to use, I tried it
through percentages but I was not successful exactly because it had
the minimum and the maximum, if it was only the minimum or only the
maximum, just multiply it by the percentage.

if you want to paste those values in the same column you need to do:
then the formula will be:
=ARRAYFORMULA(INDIRECT("A"&
MAX(IF(A3:A<>"", ROW(A3:A), )))+SORT(ROW(INDIRECT("A1:A"&
MAX(IF(A3:A<>"", ROW(A3:A), ))-2)), 1, 0)*(A1-INDIRECT("A"&
MAX(IF(A3:A<>"", ROW(A3:A), ))))/(
MAX(IF(A3:A<>"", ROW(A3:A), ))-1))

Try this formula in A2 =$A1+($A$30-$A$1)/29 and then drag down to A29

Related

VBA arrays sorting issues

I am trying to use an array to highlight specific rows in my data.
As shown in the picture, i want to extract the maximum positive profit($) and maximum negative profit($) for each respective serial numbers and highlight it in yellow. For example, Tom123's maximum +ve profit = 100 and -ve profit =-74 , thus both values are highlighted in yellow.
I already know how to highlight cells in vba, but i do not know how to get the rows that i need to highlight. Any help is much appreciated.
Add a column to identify if the column C = max profit or max loss
step 1
In D2, write =IF(OR(C2=MAX(IF((A:A=A2)*(C:C>=0),C:C,"")),C2=MIN(IF((A:A=A2)*(C:C<0),C:C,""))),TRUE,"") then press ctrl+shift+enter.
step 2
drag D2 down.
then you will see:
step 3
highlight A:C if D == true with conditional formatting

Conditional Horizontal Count of Data in Excel

I have been working on a large data set of lab testing results (previously you all have been helpful but I have a new wrinkle). Each sample has 3 columns in excel(concentration, Qualifier, MDL) and Column A has about 167 chemicals that could possible be screened for. Not all samples were screened for all chemicals, so some of the samples may have blank rows. In column B is a benchmark value that the concentration should not be greater than. I need to do the following 3 things, which i think are somewhat related. 1) Count of samples tested for a chemical, 2) Count of samples with concentrations greater than benchmark with a qualifier <>"U", and 3) Count of samples with concentrations greater than benchmark with a qualifier ="U". See above for how the results should look.
Previously, I had used an aggregate function (Suggested by you guys) to get a max and minimum for samples with a qualifier of u and without - but i can't see a way to do a count using the aggregate function.
Assuming that you meant great than, and not great than or equal to your bench mark, the following three formulas should work for your sample data. It is based on the assumption that a blank concentration means a sample was not tested.
The following counts non blank concentrations:
=SUM(--(F2<>""),--(I2<>""),--(L2<>""))
The following counts concentration greater than the bench mark and no U qualifier:
=SUM(--(AND(F2>B2,G2<>"U")),--(AND(I2>B2,J2<>"U")),--(AND(L2>B2,M2<>"U")))
The following counts concentrations greater than the bench mark and with a U qualifier:
=SUM(--(AND(F2>B2,G2="U")),--(AND(I2>B2,J2="U")),--(AND(L2>B2,M2="U")))
The above formulas are based on the chemical sitting in row 2. copy down as needed.
Note the -- in the formula above simply change the TRUE or FALSE results to an integer 1 or 0 respectively. This can also be achieved using any math operation that does not change the value such as *1 or +0.
OPTION 2
Counting With SUMPRODUCT
Again this will be on the assumption that if the concentration is empty/blank then no sample was tested for that row/chemical. Since the need is to count instead of looking for a max and min, I am opting to use SUMPRODUCT. Like AGGREGATE, it performs array like operations without actually being an array.
The following counts non blank concentrations:
=SUMPRODUCT(($F$1:$N$1="Conc")*($F2:$N2<>""))
The following counts concentration greater than the bench mark and no U qualifier:
=SUMPRODUCT(($F$1:$N$1="Conc")*($F2:$N2>$B2)*($G$1:$O$1="Q")*($G2:$O2<>"U"))
The following counts concentrations greater than the bench mark and with a U qualifier:
=SUMPRODUCT(($F$1:$N$1="Conc")*($F2:$N2>$B2)*($G$1:$O$1="Q")*($G2:$O2="U"))
The above formulas are based on the chemical sitting in row 2. copy down as needed.
Note the shift in range when checking for header Q and the value U

Named range of consistent random numbers

Background
Following on from a question I asked a while ago about getting an array of different (but not necessarily unique) random numbers to which the answer was this:
=RANDBETWEEN(ROW(A1:A10)^0,10)
To get an array of 10 random numbers between 1 and 10
The Problem
If I create a named range (called "randArray") with the formula above I hoped I would be able to reference randArray a number of times and get the same set of random numbers. Granted, they would change each time I press F9 or update the worksheet -- but change together.
This is what I get instead, two completely different sets of random numbers
I'm not surprised by this behavior but how can I achieve this without using VBA and without putting the random numbers onto the worksheet?
If you're interested
This example is intended to be MCVE. In my actual case, I am using random numbers to estimate Pi. The user stipulates how many random points to apply and gets an accordingly accurate estimation. The problem arises because I also graph the points and when there are a small number of points it's very clear to see that the estimation and the graph don't represent the same dataset
Update
I have awarded the initial bounty to #Michael for providing an interesting and different solution. I am still looking for a complete solution which allows the user to stipulate how many random points to use, and although there might not be a perfect answer I'm still interested in any other possible solutions and more than happy to put up further bounties.
Thank you to everyone who has contributed so far.
This solution generates 10 seemingly random numbers between 1 and 10 that persist for nearly 9 seconds at a time. This allows repeated calls of the same formula to return the same set of values in a single refresh.
You can modify the time frame if required. Shorter time periods allow for more frequent updates, but also slightly increase the extremely unlikely chance that some calls to the formula occur after the cutover point resulting in a 2nd set of 10 random numbers for subsequent calls.
Firstly, define an array "Primes" with 10 different prime numbers:
={157;163;167;173;179;181;191;193;197;199}
Then, define this formula that will return an array of 10 random numbers:
=MOD(ROUND(MOD(ROUND(NOW(),4)*70000,Primes),0),10)+1
Explanation:
We need to build our own random number generator that we can seed with the same value for an amount of time; long enough for the called formula to keep returning the same value.
Firstly, we create a seed: ROUND(NOW(),4) creates a new seed number every 0.0001 days = 8.64 seconds.
We can generate rough random numbers using the following formula:
Random = Seed * 7 mod Prime
https://cdsmith.wordpress.com/2011/10/10/build-your-own-simple-random-numbers/
Ideally, a sequence of random numbers is generated by taking input from the previous output, but we can't do that in a single function. So instead, this uses 10 different prime numbers, essentially starting 10 different random number generators. Now, this has less reliability at generating random numbers, but testing results further below shows it actually seems to do a pretty good job.
ROUND(NOW(),4)*70000 gets our seed up to an integer and multiplies by 7 at the same time
MOD(ROUND(NOW(),4)*70000,Prime) generates a sequence of 10 random numbers from 0 to the respective prime number
ROUND(MOD(ROUND(NOW(),4)*70000,Prime),0) is required to get us back to an integer because Excel seems to struggle with apply Mod to floating point numbers.
=MOD(ROUND(MOD(ROUND(NOW(),4)*70000,Prime),0),10)+1 takes just the value from the ones place (random number from 0 to 9) and shifts it to give us a random number from 1 to 10
Testing results:
I generated 500 lots of 10 random numbers (in columns instead of rows) for seed values incrementing by 0.0001 and counted the number of times each digit occurred for each prime number. You can see that each digit occurred nearly 500 times in total and that the distribution of each digit is nearly equal between each prime number. So, this may be adequate for your purposes.
Looking at the numbers generated in immediate succession you can see similarities between adjacent prime numbers, they're not exactly the same but they're pretty close in places, even if they're offset by a few rows. However, if the refresh is occurring at random intervals, you'll still get seemingly random numbers and this should be sufficient for your purposes. Otherwise, you can still apply this approach to a more complex random number generator or try a different mix of prime numbers that are further apart.
Update 1: Trying to find a way of being able to specify the number of random numbers generated without storing a list of primes.
Attempt 1: Using a single prime with an array of seeds:
=MOD(ROUND(MOD(ROUND(NOW()+ROW(OFFSET(INDIRECT("A1"),0,0,SampleSize))/10000,4)*70000,1013),0),10)+1
This does give you an even distribution, but it really is just repeating the exact same sequence of 10 numbers over and over. Any analysis of the sample would be identical to analysing =MOD(ROW(1:SampleSize),10)+1. I think you want more variation than that!
Attempt 2: Working on a 2-dimensional array that still uses 10 primes....
Update 2: Didn't work. It had terrible performance. A new answer has been submitted that takes a similar but different approach.
OK, here's a solution where users can specify the number of values in defined name SAMPLESIZE
=MOD(ROUND(MOD(ROUND(NOW()+ROW(OFFSET(INDIRECT("A1"),0,0,SampleSize)),4)*10000*163,1013),0)+ROUND(MOD(ROUND(NOW()+ROW(OFFSET(INDIRECT("A1"),0,0,SampleSize))*2,4)*10000*211,1013),0)+ROUND(MOD(ROUND(NOW()+ROW(OFFSET(INDIRECT("A1"),0,0,SampleSize))*3,4)*10000*17,1013),0)+ROUND(MOD(ROUND(NOW()+ROW(OFFSET(INDIRECT("A1"),0,0,SampleSize))*5,4)*10000*179,53),0)+ROUND(MOD(ROUND(NOW()+ROW(OFFSET(INDIRECT("A1"),0,0,SampleSize))*7,4)*10000*6101,1013),0),10)+1
It's a long formula, but has good efficiency and can be used in other functions. Attempts at a shorter formula resulted in unusably poor performance and arrays that for some reason couldn't be used in other functions.
This solution combines 5 different prime number generators to increase variety in the generated random numbers. Some arbitrary constants were introduced to try to reduce repeating patterns.
This has correct distribution and fairly good randomness. Repeated testing with a SampleSize of 10,000 resulted in frequencies of individual numbers varying between 960 and 1040 with no overall favoritism. However it seems to have the strange property of never generating the same number twice in a row!
You can achieve this using just standard spreadsheet formulas.
One way is to use the so called Lehmer random number method. It generates a sequence of random numbers in your spreadsheet that stays the same until you change the "seed number", a number you choose yourself and will recreate a different random sequence for each seed number you choose.
The short version:
In cell B1, enter your "seed" number, it can be any number from 1 to 2,147,483,647
In cell B2 enter the formula =MOD(48271*B1,2^31-1) , this will generate the first random number of your sequence.
Now copy this cell down as far as the the random sequence you want to generate.
That's it. For your named range, go ahead and name the range from B2 down as far as your sequence goes. If you want a different set of numbers, just change the seed in B1. If you ever want to recreate the same set of numbers just use the same seed and the same random sequence will appear.
More details in this tutorial:
How to generate random numbers that don't change in Excel and Google Sheets
It's not a great answer but considering the limitation of a volatile function, it is definitely a possible answer to use the IF formula with Volatile function and a Volatile variable placed somewhere in the worksheet.
I used the below formula to achieve the desired result
=IF(rngIsVolatile,randArray,A1:A10)
I set cell B12 as rngIsVolatile. I pasted the screenshots below to see it in working.
When rngIsVolatile is set to True, it picks up new values from randArray:
When rngIsVolatile is set to False, it picks up old values from A1:A10:

Weighted average function

I'm trying to create a function that takes the weighted average of an array. I am creating a presentation that shows rates ($) and revenue by market for a client with a weighted average rate per product at the bottom. I could manually find each markets % share of total revenue and then multiply each market's % factor by it's rate and then add all of these values up to find the weighted average rate, but I want to create a function to do it for me. I want to do the following:
For the following client data (fake):
-Asia $16 $200,000
-Europe $9 $50,000
-N. America $21 $100,000
-Africa $25 $250,000
I need to find the weighted average rate across all markets.
Function WeightedAverage(array, weightarray)
#"array" being {$16,$9,$21,$25} and "weightarray" being {$200,000, $50,000, $100,000, $250,000}
WeightedAverage = SumProduct(array, weightvalues)
weightvalues = an array of values like so {$200,000/sum(weightarray), $50,000/sum(weightarray), $100,000/sum(weightarray), $250,000/sum(weightarray)}
End Function
This should return a weighted average rate of $20.
Can someone help me accomplish this?
You don't need VBA -- a simple formula works. If your data is in cells A1:C4, enter the following formula:
=SUMPRODUCT(B1:B4,C1:C4/SUM(C1:C4))
In this version of the formula I am treating C1:C4/SUM(C1:C4) much like an array formula, which converts the array of numbers (200,000, 50,000, etc.) into the corresponding array of weights (0.33, 0.083, etc.). In many contexts, this would require explicitly treating the expression as an array formula, but sumproduct is a rather powerful function which can apply whole-array formulas to its arguments. See this for a nice discussion.
In this particular case
=SUMPRODUCT(B1:B4,C1:C4)/SUM(C1:C4)
also works and corresponds to Merely Useful's answer in the comments, but I'll leave my answer as it is since it is useful to know that sumproduct can in effect evaluate array formulas in its arguments, even if the overall sumproduct isn't entered as an array formula itself.
Well, you don't need a VBA function for this, an array formula will do:
=SUM(A1:A4*B1:B4)/SUM(B1:B4)
(Press Ctrl+Enter when entering the formula)

simplified _resample_ algorithm in matlab

I am generating a variable size rows of samples from a DSP algorithm.
I mean each of the row contains random number of elements(Well, depending on the input).
I would like to resize into a specific number of samples per row.
Ex: column count in each row: 15 24 41 09 27
Say I would like to make it 30 element in a row.
Each of the row is a digitized curve samples.
I'm interested in making it contain equisized sample elements.
I think you need to resample your row values, the idea is roughly like this:
interpolate each row to a continuous curve
quantize each curve to a fixed number of values (30)
Obviously, for row with >30 values, you will lose some information.

Resources