I'm hoping there is SPSS syntax that I can use to randomly select a number from among a couple of variables. For example: the data lists the ages of respondent's children in four variables - Age1 Age2 Age3 Age4
Resp 1: 3 6 8
Resp 2: 2 10
Resp 3: 4
I want to create a variable that stores a randomly selected age for each respondent - something like:
Resp 1: 6
Resp 2: 2
Resp 3: 4
The code I'm using at the moment:
COUNT kids=age1 to age4 (1 thru 16).
COMPUTE rand=RND(RV.UNIFORM(1, kids),1).
DO REPEAT
x1=age1 to age4
/x2=1 to 4.
IF (rand=x2) random_age=x1.
END REPEAT.
Here is my suggested code for the task.
First creating some sample data to demonstrate on:
data list list/id age1 to age4 (5f2).
begin data
1, 4, 5, 6, 7
2, 4, 5, 6,
3, 6, 7,,
4, 8,,,
5, 5, 6, 7,
6, 10,,,
end data.
Now to randomly select one of the ages:
compute numages=4-nmiss(age1 to age4).
compute SelectThis = rnd(uniform(numages)+.5).
do repeat ag=age1 to age4 /ind=1 to 4.
if SelectThis=ind SelectedRandAge=ag.
end repeat.
exe.
Well, here's my attempt for the time being:
data list list /age1 to age4.
begin data.
10 9 5 8
3
13 15
1 4 5
4 7 8 2
end data.
count valid=age1 to age4 (lo thru hi).
compute s=trunc(1+uniform(valid)).
vector age=age1 to age4.
compute myvar=age(s).
list age1 to age4 myvar.
Related
I am still pretty new at programming and I would appreciate any help on how to approach the following problem:
Given a matrix (3x5)
a = [1 2 3 4 5;
6 7 8 9 10;
11 12 13 14 15;]
I want to iterate through every row
For each row, I want each element to be checked
With each element, I want to store a separate array that holds the element and the next 2 elements.
Ex:
Row 1 = [1 2 3 4 5]
For element 1
return newArray = [1 2 3]
For element 2
return newArray = [2 3 4]
Getting stuck on part 3. How to make the for loop check only up to the next 2 elements and then continue to the next element in the row.
I took a shot at solving what you asked for, but I agree with the others that you need to think more about what you are trying to do and what you want your output to look like. Your request does not sound like something a beginner programmer would realistically use. I am not sure what shape you want to store your "separate array"s in. I have options below for keeping them in a vector or in the original shape of a.
function nexttwo(row, i)
newarray::Vector{Any} = [row[i]]
for j=1:2
i+=1
if length(row) >= i
push!(newarray, row[i])
else
push!(newarray, nothing)
end
end
return newarray
end
function collectnexttwo(a)
result_collection = []
for i in axes(a,1)
for j in axes(a,2)
row = a[i,:]
newarray = nexttwo(row, j)
push!(result_collection, newarray)
end
end
return result_collection
end
function restoreshape(v, a)
permutedims(reshape(v, reverse(size(a))))
end
julia> a = [1 2 3 4 5; 6 7 8 9 10; 11 12 13 14 15;]
3×5 Matrix{Int64}:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
julia> result = restoreshape(collectnexttwo(a), a)
3×5 Matrix{Any}:
Any[1, 2, 3] Any[2, 3, 4] Any[3, 4, 5] Any[4, 5, nothing] Any[5, nothing, nothing]
Any[6, 7, 8] Any[7, 8, 9] Any[8, 9, 10] Any[9, 10, nothing] Any[10, nothing, nothing]
Any[11, 12, 13] Any[12, 13, 14] Any[13, 14, 15] Any[14, 15, nothing] Any[15, nothing, nothing]
I think that you have some problems with the statement of what you want to achieve. That can often make a programming assignment much harder.
Restating what you have already:
I want to iterate through every row
This is pretty easy
for row = 1:size(a)[1]
...
end
For each row, I want each element to be checked
This is where things begin to get squishy? What do you mean by "checked". Let's assume you have some function called checkElement.
With each element, I want to store a separate array that holds the element and the next 2 elements.
How long do you want that separate array to live? Do you just want to hold 3 elements? Or three elements for every cell of the original (i.e. have a 3x5x3 result for a 3x5 input like you show)
Also, what do you want to do about elements 4 and 5 in each row? What values do you want to use for their "next" elements? You could use missing as a value or NaN. Or you could make the result just not contain the problematic inputs.
If you answer these questions, you are likely to find it much easier to write the code you need.
I'm trying to generate new rows based on values in a certain column. In current data as you can see 'days_left' column does not have all sequential values.
current = {'assignment': [1,1,1,1,2,2,2,2,2], 'days_left': [1, 2, 5, 9,1, 3, 4, 8, 13]}
dfcurrent = pd.DataFrame(data=current)
dfcurrent
While I want to generate rows into that dataframe to create make sequential list for for 'days_left' for each 'assignment'. Please see the desidered output below:
desired = {'assignment': [1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2],
'days_left': [1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,10,11,12,13]}
dfdesired = pd.DataFrame(data=desired)
dfdesired
Note: The original data is much bigger and has other columns as well but I just simplified it for this question.
Could you please help me how I can solve this?
Thank you very much in advance!
You can iterate through the rows of the current dataframe and create a new dataframe. For each days_left range, copy the current row to the new dataframe and update the days_left column value.
Try this code:
import pandas as pd
current = {'assignment': [1,1,1,1,2,2,2,2,2], 'days_left': [1, 2, 5, 9, 1, 3, 4, 8, 13]}
dfc = pd.DataFrame(data=current)
dfd = pd.DataFrame() # new dataframe
for r in range(1,len(dfc)): # start at 2nd row
for i in range(dfc.iloc[r-1]['days_left'],dfc.iloc[r]['days_left']): # fill gap of missing numbers
dfd = dfd.append(dfc.iloc[r]) # copy row
dfd.reset_index(drop=True, inplace=True) # prevent index duplication
dfd.loc[len(dfd)-1, 'days_left'] = i # update column value
if r == len(dfc)-1 or dfc.iloc[r+1]['assignment']!=dfc.iloc[r]['assignment']: # last entry in assignment
dfd = dfd.append(dfc.iloc[r]) # copy row
dfd.reset_index(drop=True, inplace=True) # prevent index duplication
dfd = dfd.astype(int) # convert all data to integers
print(dfd.to_string(index=False))
Output
assignment days_left
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
2 1
2 2
2 3
2 4
2 5
2 6
2 7
2 8
2 9
2 10
2 11
2 12
2 13
Working on a dicegame for school and I have trouble figuring out how to do automatic calculation of the result. (we don't have to do it automatically, so I could just let the player choose which dice to use and then just check that the user choices are valid) but now that I have started to think about it I can't stop...
the problem is as follows:
I have six dice, the dice are normal dice with the value of 1-6.
In this example I have already roled the dice and they have the following values:
[2, 2, 2, 1, 1, 1]
But I don't know how to calulate all combinations so that as many dicecombinations as possible whose value combined(addition) are 3 (in this example) are used.
The values should be added together (for example a die with value 1 and another die with the value 2 are together 3) then there are different rounds in the game where the aim is to get different values (which can be a combination(addition) of die-values for example
dicevalues: [2, 2, 2, 2, 2, 2]
could give the user a total of 12 points if 4 is the goal for the current round)
2 + 2 = 4
2 + 2 = 4
2 + 2 = 4
if the goal of the round instead where 6 then the it would be
2 + 2 + 2 = 6
2 + 2 + 2 = 6
instead which would give the player 12 points (6 + 6)
[1, 3, 6, 6, 6, 6]
with the goal of 3 would only use the dice with value 3 and discard the rest since there is no way to add them up to get three.
2 + 1 = 3
2 + 1 = 3
2 + 1 = 3
would give the user 9 points.
but if it where calculated the wrong way and the ones where used up together instead of each 1 getting apierd with a two 1 + 1 + 1 which would only give the player 3 points och the twos couldn't be used.
Another example is:
[1, 2, 3, 4, 5, 6]
and all combinations that are equal to 6 gives the user points
[6], [5, 1], [4 ,2]
user gets 18 points (3 * 6)
[1 ,2 ,3], [6]
user gets 12 points (2 * 6) (Here the user gets six points less due to adding upp 1 + 2 + 3 instead of doing like in the example above)
A dice can have a value between 1 and 6.
I haven't really done much more than think about it and I'm pretty sure that I could do it right now, but it would be a solution that would scale really bad if I for example wanted to use 8 dices instead and every time I start programming on it I start to think that have to be a better/easier way of doing it... Anyone have any suggestion on where to start? I tried searching for an answer and I'm sure it's out there but I have problem forumulating a query that gives me relevant result...
With problems that look confusing like this, it is a really good idea to start with some working and examples. We have 6 die, with range [1 to 6]. The possible combinations we could make therefore are:
target = 2
1 combination: 2
2 combination: 1+1
target = 3
1 combination: 3
2 combination: 2+1
3 combination: 1+1+1
target = 4
1 combination: 4
2 combination: 3+1
2+2
3 combination: 2+1+1
4 combination: 1+1+1+1
target = 5
1 combination: 5
2 combination: 4+1
3+2
3 combination: 2+2+1
4 combination: 2+1+1+1
5 combination: 1+1+1+1+1
See the pattern? Hint, we go backwards from target to 1 for the first number we can add, and then given this first number, and the size of the combination, there is a limit to how big subsequent numbers can be!
There is a finite list of possible combinations. You can by looking for 1 combination scores, and remove these from the die available. Then move on to look for 2 combination scores, etc.
If you want to read more about this sub-field of mathematics, the term you need to look for is "Combinatorics". Have fun!
I used the quicksort algorithm to sort
11 8 9 4 2 5 3 12 6 10 7
and I got the list:
4 3 2 5 9 11 8 12 6 10 7.
5 was used as a pivot. Now I am stuck. How do I proceed to sort the lowersublist and the uppersublist?
pivot=5 11 8 9 4 2 5 3 12 6 10 7
Move pivot to position 0 5 8 9 4 2 11 3 12 6 10 7
i (position 1 = 8)
j (position 6 = 3) ⇒ swap 8 and 3 5 3 9 4 2 11 8 12 6 10 7
i (position 2 = 9)
j (position 4 = 2) ⇒ swap 9 and 2 5 3 2 4 9 11 8 12 6 10 7
i (position 3 = 4)
– no smaller elements than 5 ⇒ swap 5 and 4 4 3 2 5 9 11 8 12 6 10 7
– list after the partition
Quicksort is a recursive algorithm. Once you have sorted the elements by the pivot, you get two sets of items. The first with all elements smaller or equal to the pivot, and the second with all elements larger than the pivot. What you do now, is that you apply quicksort again to each of these sets (with an appropriate pivot).
To do this, you will have to choose a new pivot every time. You can do something like always pick the first element, or draw one at random.
Once you reach a point where a set contains only one element, you stop.
A good way to understand these things is to try to sort a deck of cards using this algorithm. All cards are face down, and you are only allowed to look at two cards at a time, compare these and switch them if necessary. You must pretend to not remember any of the cards that are face down for that to work.
A key component of the algorithm is that the chosen pivot value came from the original list, which means (in your case) the element with the value 5 is now in the correct final position after the first partitioning:
4 3 2 5 9 11 8 12 6 10 7
This should be fairly obvious and follows simple intuition. If every element to the left of an item is smaller than that item and every element to the right is larger, then the item must be in the correct, sorted position.
The insight necessary to understanding the entire Quicksort algorithm is that you can just keep doing this to each of the sublists -- the list of values to the left of the pivot and the list containing all values to the right -- to arrive at the final, sorted list. This is because:
Each partitioning puts one more element in its proper position
Each iteration removes one element -- the pivot -- from the list of elements left to process (which is why we'll eventually reach the base case of zero (or one, depending on how you do it) elements)
Let's assume you chose the partition value of 5 based on the following pseudo-code:
Math.floor(list.length / 2)
For our purposes, the actual choice of a pivot doesn't really matter. This one works for your orginal choice, so we'll go with it. Now, let's play this out 'till the end (starting where you left off):
concat(qs([4 3 2]), 5, qs([9 11 8 12 6 10 7])) =
concat(qs([2]), 3, qs([4]), 5, qs([9, 11, 8, 6, 10, 7]), 12, qs([])) =
concat(2, 3, 4, 5, qs([6, 7]), 8, qs([9, 11, 10]), 12) =
concat(2, 3, 4, 5, qs([6]), 7, qs([]), 8, qs([9, 10]), 11, qs([]), 12) =
concat(2, 3, 4, 5, 6, 7, 8, qs([9]), 10, qs([]), 11, 12) =
concat(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
Note that each time you see a single call to qs it will follow this pattern:
qs(<some_left_list>), <the_pivot>, qs(<some_right_list>)
And each call of qs on one line results in two more such calls on the following line (representing the processing of both new sublists (except note that I immediately decompose calls to qs on single-value lists)).
It's a good idea to go through this exercise yourself. Yes, with actual pen and paper.
I have written an algorithm which iteratively solves the problem. The first iteration consists of 6 steps and all the following iterations consist of 5 steps (first step is skipped).
What I want to calculate is the current (local) step in the iteration from current global step.
For example if there are 41 steps in total which means there are 8 iterations:
indices from 1 to 6 belong to 1st iteration
indices from 7 to 11 belong to second iteration
...
For calculating the current iteration I have written the following code:
if(currentStep <= 6)
iteration = 1;
else
iteration = floor((currentStep - 7)/5) + 2;
end
The problem remains in calculating local steps.
in first iteration the performed steps are: 1, 2, 3, 4, 5, 6
in all the following iterations the performing steps are 2, 3, 4, 5, 6
So what has to be done is to transform the array of global steps
[1 2 3 4 5 6 7 8 9 10 11 12 13 ... 41]
into array of local steps
[1 2 3 4 5 6 2 3 4 5 6 2 3 ... 6].
I would appreciate if anyone could help in finding the solution to a given problem.
Thank you!
local_step = [1 mod([0:39],5)+2]
Here is the solution in python:
L = range(1,42) # so L = [1,2,...,41]
s = [(i-2)%5+2 for i in L]
# adjust for the first step:
s[0]=1
# now s = [1,2,3,4,5,6,2,3,4,...,5,6]
Check this :
if(currentStep <= 6)
{localStep = currentStep;}
else
{localStep = currentStep - ((iteration - 1) * 5);}