Counting occurrences of values in spss - variables

I have 50 variables, named w1 to w50, and each holds a value from 1 to 20. I want to create variables showing the number of occurrences of each of these values. This is what I'd like to do, but SPSS seems to have a problem with me using #n in the COUNT command.
COMPUTE #n = 1 .
DO REPEAT x = num1 to num20 .
COMPUTE x = 0 .
COUNT x = w1 to w50 (#n) .
COMPUTE #n = #n + 1 .
END REPEAT .
This is the error message I get:
Error # 4772 in column 24. Text: #n
On the COUNT command, the parenthesized value list is syntactically invalid.
Execution of this command stops.

You cannot supply a variable as the value list in the COUNT command. Fortunately the work around for your example is quite simple - you can use a stand in increment on the DO REPEAT:
DO REPEAT x = num1 to num20 /#i = 1 to 20.
COUNT x = w1 to w50 (#i).
END REPEAT.
Full example below.
**********************************************.
*creating fake data.
data list free / ID.
begin data
1
2
end data.
vector w(50,F2.0).
loop #i = 1 to 50.
compute w(#i) = TRUNC(RV.UNIFORM(1,21)).
end loop.
vector num(20,F2.0).
execute.
*making new vector.
DO REPEAT x = num1 to num20 /#i = 1 to 20.
COUNT x = w1 to w50 (#i).
END REPEAT.
EXECUTE.
**********************************************.

Related

The sum of the first natural 100 numbers

new to coding,
Quick Homework problem Im having trouble on.
I must find the sum of the first 100 natural numbers. 1+2+3+4, and so on. While using "while loops".
This is what I have so far.
Dim sum, count As Integer
Const num As Integer = 1
Console.WriteLine("The Sum of the first 100 natural numbers is:")
count = num + 1
While count <= 100
Count = num + count
End While
Sum = count
Console.WriteLine("{0}", sum)
Console.ReadLine()
I know for a fact the math and while loop is incorrect, but Im not sure how to fix it. I keep getting 101 as my answer.
You do not need the num constant and the line: count = num + 1
While count <= 100
sum += count
count += 1
End While
I know you are learning and the solution must use a While loop but for fun see what you can do in 2 lines of code.
Dim arrNumbers = Enumerable.Range(1, 100).ToArray
Console.WriteLine(arrNumbers.Sum)
Since your question title asked for sums of all [1 - 100] as well as the evens and odds, here is some LINQ for each one
Dim sum = Enumerable.Range(1, 100).Sum()
Dim sumEvens = Enumerable.Range(1, 100).Sum(Function(i) If(i Mod 2 = 0, i, 0))
Dim sumOdds = Enumerable.Range(1, 100).Sum(Function(i) If(i Mod 2 = 0, 0, i))
Console.WriteLine($"Sum: {sum}, Sum evens: {sumEvens}, Sum odds: {sumOdds}")
Sum: 5050, Sum evens: 2550, Sum odds: 2500
Enumerable.Range(1, 100) creates your sequence of all [1 - 100]. Call the LINQ function Sum to simply get the sum, or you can pass a lambda function to Sum to transform the numbers. Use Mod to select evens or odds. The method above sets odds to 0 for the evens, and vice-versa for the odds.
An alternative to this method of transforming the sequence is to use Where to select only even numbers then Sum, which may be more readable.
Dim sumEvens = Enumerable.Range(1, 100).Where(Function(i) i Mod 2 = 0).Sum()
With your code you've done a few things in a weird way.
Let's simplify the code and see what's going wrong.
To start with you are setting num as a constant to the value of 1. Since it's not changing, we'll put the value in directly.
You'd then have this:
count = 1 + 1
While count <= 100
count = 1 + count
End While
sum = count
So that means count will start at 2 and goes up by one until the value of count is greater than 100 - and that's when it is 101.
Then you set sum to count and you get 101.
What you needed to do was start count as 1 and sum up the values inside the loop.
count = 1
While count <= 100
sum = sum + count
count = count + 1
End While
And that gives the correct result of 5050.
While count <= 100
num += count
count += 1
End While
Sum = num

Running time of nested while loops

Function f(n)
s = 0
i = 1
while i < 7n^1/2 do
j = i
while j > 5 do
s = s + i -j
j = j -2
end
i = 5i
end
return s
end f
I am trying to solve the running time for big theta with the code above. I have been looking all over the place for something to help me with an example, but everything is for loops or only one while loop. How would you go about this problem with nested while loops?
Let's break this down into two key points:
i starts from 1, and is self-multiplied by 5, until it is greater than or equal to 7 sqrt(n). This is an exponential increase with logarithmic number of steps. Thus we can change the code to the following equivalent:
m = floor(log(5, 7n^(1/2)))
k = 0
while k < m do
j = 5^k
// ... inner loop ...
end
For each iteration of the outer loop, j starts from i, and decreases in steps of 2, until it is less than or equal to 5. Note that in the first execution of the outer loop i = 1, and in the second i = 5, so the inner loop is not executed until the third iteration. The loop limit means that the final value of j is 7 if k is odd, and 6 if even (you can check this with pen and paper).
Combining the above steps, we arrive at:
First loop will do 7 * sqrt(n) iterations. Exponent 1/2 is the same as sqrt() of a number.
Second loop will run m - 2 times since first two values of i are 1 and 5 respectively, not passing the comparison.
i is getting an increment of 5i.
Take an example where n = 16:
i = 1, n = 16;
while( i < 7 * 4; i *= 5 )
//Do something
First value of i = 1. It runs 1 time. Inside loop will run 0 times.
Second value of i = 5. It runs 2 times. Inside loop will run 0 times.
Third value of i = 25. It runs 3 times. Inside loop will run 10 times.
Fourth value of i = 125. It stops.
Outer iterations are n iterations while inner iterations are m iterations, which gives O( 7sqrt(n) * (m - 2) )
IMO, is complex.

SPSS: DO REPEAT with different numbers of matched variables

I have a dataset where each case has the following set of variables:
VarA1.1 to VarA25.185 (total of 4625 variables)
VarB.1 to VarB.185 (total of 185 variables)
For each case, VarA1.1, VarA2.1, VarA3.1, etc. are all linked to the same VarB.1.
I want to use a DO REPEAT function to search through each .1 instance using both VarA and VarB.
Example code:
DO REPEAT VarA = VarA1.1 to VarA25.185
/ VarB = VarB.1 to VarB.185.
if (VarA = X) AND ((VarB-Y)<0)
VarC = Z.
END REPEAT.
EXE.
However, it seems that because there are different numbers of variables in the repeat list of VarA and VarB, they don't pair up. I want to associate each VarA#(1-25).1 with VarB.1, each VarA#(1-25).2 with each VarB.2, etc. up to VarB.185 so that in the repeat function the correct pairing of variables is used.
Thanks!
Another way to do this is to use a LOOP on the outside and a DO REPEAT on the inside. So here is some example data, with just three A variables that go to 1 to 10.
SET SEED 10.
INPUT PROGRAM.
LOOP Id = 1 TO 100.
END CASE.
END LOOP.
END FILE.
END INPUT PROGRAM.
DATASET NAME Sim.
*Making random data.
VECTOR A1.(10).
VECTOR A2.(10).
VECTOR A3.(10).
VECTOR B.(10).
NUMERIC X Y.
DO REPEAT a = A1.1 TO Y.
COMPUTE a = RV.BERNOULLI(0.5).
END REPEAT.
EXECUTE.
So here is the part you want to pay attention to. Your DO REPEAT currently loops over the 25 variables. This switches it though, so the LOOP part goes over the 25 variables, but the DO REPEAT goes over each of your A vectors.
VECTOR A1 = A1.1 TO A1.10.
VECTOR A2 = A2.1 TO A2.10.
VECTOR A3 = A3.1 TO A3.10.
VECTOR B = B.1 TO B.10.
VECTOR C.(10).
LOOP #i = 1 TO 10.
DO REPEAT A = A1 A2 A3.
IF (A(#i) = X) AND (B(#i)-Y<0) C.(#i) = B(#i).
END REPEAT.
END LOOP.
EXECUTE.
Code golf it is probably not going to beat the macro approach, since you have to define all of those VECTOR statements. But I think it is a conceptually clear way to write the program.
It looks like what you are trying to do is loop over 25 variables but repeat this for 185 variables.
It would be more intutive to use SPSS Macros to achieve this. Stepping through the below will demonstrate the building blocks for solving your data problem.
DEFINE !MyMacroName ()
SET MPRINT ON.
/* Generate some example data to match desired data format*/.
set seed = 10.
input program.
loop #i = 1 to 50.
compute case = #i.
end case.
end loop.
end file.
end input program.
dataset name sim.
execute.
!do !i =1 !to 25
vector !concat('VarA',!i,'.(185, F1.0).').
do repeat v = !concat('VarA',!i,'.1') to !concat('VarA',!i,'.185').
compute v = TRUNC(RV.UNIFORM(1,6)).
end repeat.
!doend
vector VarB.(185, F1.0).
do repeat v = VarB.1 to VarB.185.
compute v = TRUNC(RV.UNIFORM(1,6)).
end repeat.
execute.
/* Solve actual problem */.
!do !i =1 !to 185
!do !j = 1 !to 25
if (!concat('VarA',!j,'.',!i) = !concat('VarB.',!i)) !concat('VarC', !j)=1.
!doend
!doend
SET MPRINT OFF.
!ENDDEFINE.
/* Run macro */.
!MyMacroName.

print even number it doesn't work

n = 1
a = 2
num = 2*a*n
while n <= 100
print (num)
n = n+1
I want to print even number between 1< num <= 100
but, computer prints only 4
Because you calculate the value for num only once num = 2*a*n //= 4 . So you just print n-times the value 4. If you want to recalculate it you have to put it inside the loop
while n <= 100
num = 2*a*n
print (num)
n = n+1
Be patient that i just reused your pseudo code syntax
In your solution , num is not changing , it keeps on value 4
So you should change it on every iteration :
n=1
a=2
num=2*a*n //here num=4
while n<=100
print (num)
n=n+1
num=2*a*n //so that now num is changed
Good luck

How to choose a range for a loop based upon the answers of a previous loop?

I'm sorry the title is so confusingly worded, but it's hard to condense this problem down to a few words.
I'm trying to find the minimum value of a specific equation. At first I'm looping through the equation, which for our purposes here can be something like y = .245x^3-.67x^2+5x+12. I want to design a loop where the "steps" through the loop get smaller and smaller.
For example, the first time it loops through, it uses a step of 1. I will get about 30 values. What I need help on is how do I Use the three smallest values I receive from this first loop?
Here's an example of the values I might get from the first loop: (I should note this isn't supposed to be actual code at all. It's just a brief description of what's happening)
loop from x = 1 to 8 with step 1
results:
x = 1 -> y = 30
x = 2 -> y = 28
x = 3 -> y = 25
x = 4 -> y = 21
x = 5 -> y = 18
x = 6 -> y = 22
x = 7 -> y = 27
x = 8 -> y = 33
I want something that can detect the lowest three values and create a loop. From theses results, the values of x that get the smallest three results for y are x = 4, 5, and 6.
So my "guess" at this point would be x = 5. To get a better "guess" I'd like a loop that now does:
loop from x = 4 to x = 6 with step .5
I could keep this pattern going until I get an absurdly accurate guess for the minimum value of x.
Does anybody know of a way I can do this? I know the values I'm going to get are going to be able to be modeled by a parabola opening up, so this format will definitely work. I was thinking that the values could be put into a column. It wouldn't be hard to make something that returns the smallest value for y in that column, and the corresponding x-value.
If I'm being too vague, just let me know, and I can answer any questions you might have.
nice question. Here's at least a start for what I think you should do for this:
Sub findMin()
Dim lowest As Integer
Dim middle As Integer
Dim highest As Integer
lowest = 999
middle = 999
hightest = 999
Dim i As Integer
i = 1
Do While i < 9
If (retVal(i) < retVal(lowest)) Then
highest = middle
middle = lowest
lowest = i
Else
If (retVal(i) < retVal(middle)) Then
highest = middle
middle = i
Else
If (retVal(i) < retVal(highest)) Then
highest = i
End If
End If
End If
i = i + 1
Loop
End Sub
Function retVal(num As Integer) As Double
retVal = 0.245 * Math.Sqr(num) * num - 0.67 * Math.Sqr(num) + 5 * num + 12
End Function
What I've done here is set three Integers as your three Min values: lowest, middle, and highest. You loop through the values you're plugging into the formula (here, the retVal function) and comparing the return value of retVal (hence the name) to the values of retVal(lowest), retVal(middle), and retVal(highest), replacing them as necessary. I'm just beginning with VBA so what I've done likely isn't very elegant, but it does at least identify the Integers that result in the lowest values of the function. You may have to play around with the values of lowest, middle, and highest a bit to make it work. I know this isn't EXACTLY what you're looking for, but it's something along the lines of what I think you should do.
There is no trivial way to approach this unless the problem domain is narrowed.
The example polynomial given in fact has no minimum, which is readily determined by observing y'>0 (hence, y is always increasing WRT x).
Given the wide interpretation of
[an] equation, which for our purposes here can be something like y =
.245x^3-.67x^2+5x+12
many conditions need to be checked, even assuming the domain is limited to polynomials.
The polynomial order is significant, and the order determines what conditions are necessary to check for how many solutions are possible, or whether any solution is possible at all.
Without taking this complexity into account, an iterative approach could yield an incorrect solution due to underflow error, or an unfortunate choice of iteration steps or bounds.
I'm not trying to be hard here, I think your idea is neat. In practice it is more complicated than you think.