finish separation of sample method #421

This commit is contained in:
Josh de Leeuw 2017-07-06 15:48:33 -04:00
parent 94547dd5ba
commit 23397a0da7
7 changed files with 92 additions and 39 deletions

View File

@ -232,10 +232,10 @@ output: shuffledArray = {
*/
```
---
## jsPsych.randomization.sample
## jsPsych.randomization.sampleWithReplacement
```
jsPsych.randomization.sample(array, sampleSize, withReplacement)
jsPsych.randomization.sampleWithReplacement(array, sampleSize, weights)
```
### Parameters
@ -244,7 +244,7 @@ Parameter | Type | Description
----------|------|------------
array | array | The array of values to sample from
sampleSize | numeric | The number of samples to draw
withReplacement | boolean | If `true`, then sampling will be with replacement. Otherwise, sampling is without replacement.
weights | array | The relative weight of each element in `array`. This array is normalized, so the values do not need to sum to 1. The length must match the length of `array`.
### Return value
@ -252,7 +252,51 @@ An array containing the sample.
### Description
This method returns a sample drawn at random from a set of values. Sampling can be with replacement (items can be chosen more than once) or without replacement (items may only be chosen once).
This method returns a sample drawn at random from a set of values with replacement. The relative probability of drawing each item can be controlled by specifying the `weights`.
### Examples
#### Sample with equal probability
```javascript
var myArray = [1,2,3,4,5];
var sample = jsPsych.randomization.sampleWithReplacement(myArray, 10);
// output: sample = [3, 1, 2, 2, 5, 1, 4, 3, 1, 5];
```
#### Sample with unequal probability
```javascript
var myArray = [1,2,3,4,5];
var sample = jsPsych.randomization.sampleWithReplacement(myArray, 10, [6,1,1,1,1]);
// output: sample = [3, 4, 5, 1, 2, 1, 3, 1, 1, 1];
```
---
## jsPsych.randomization.sampleWithoutReplacement
```
jsPsych.randomization.sampleWithoutReplacement(array, sampleSize)
```
### Parameters
Parameter | Type | Description
----------|------|------------
array | array | The array of values to sample from
sampleSize | numeric | The number of samples to draw
### Return value
An array containing the sample.
### Description
This method returns a sample drawn at random from a set of values without replacement. The sample size must be less than or equal to the length of the array.
### Examples
@ -261,21 +305,11 @@ This method returns a sample drawn at random from a set of values. Sampling can
```javascript
var myArray = [1,2,3,4,5];
var sample = jsPsych.randomization.sample(myArray, 2, false);
var sample = jsPsych.randomization.sampleWithoutReplacement(myArray, 2);
// output: sample = [3,2];
```
#### Sample with replacement
```javascript
var myArray = [1,2,3,4,5];
var sample = jsPsych.randomization.sample(myArray, 8, true);
// output: sample = [3,2,1,5,3,3,4,2];
```
---
## jsPsych.randomization.shuffle

View File

@ -46,7 +46,8 @@ Every jsPsych experiment utilizes the core library (contained in the `jspsych.js
* [jsPsych.randomization.factorial](jspsych-randomization.md#jspsychrandomizationfactorial)
* [jsPsych.randomization.randomID](jspsych-randomization.md#jspsychrandomizationrandomid)
* [jsPsych.randomization.repeat](jspsych-randomization.md#jspsychrandomizationrepeat)
* [jsPsych.randomization.sample](jspsych-randomization.md#jspsychrandomizationsample)
* [jsPsych.randomization.sampleWithReplacement](jspsych-randomization.md#jspsychrandomizationsamplewithreplacement)
* [jsPsych.randomization.sampleWithoutReplacement](jspsych-randomization.md#jspsychrandomizationsamplewithoutreplacement)
* [jsPsych.randomization.shuffle](jspsych-randomization.md#jspsychrandomizationshuffle)
* [jsPsych.randomization.shuffleNoRepeats](jspsych-randomization.md#jspsychrandomizationshufflenorepeats)

View File

@ -19,7 +19,7 @@ Often it is useful to add a piece of data to *all* of the trials in the experime
var subject_id = jsPsych.randomization.randomID(15);
// pick a random condition for the subject at the start of the experiment
var condition_assignment = jsPsych.randomization.sample(['conditionA', 'conditionB', 'conditionC'],1)[0];
var condition_assignment = jsPsych.randomization.sampleWithoutReplacement(['conditionA', 'conditionB', 'conditionC'], 1)[0];
// record the condition assignment in the jsPsych data
// this adds a property called 'subject' and a property called 'condition' to every trial

View File

@ -186,6 +186,24 @@ var face_name_procedure = {
}
```
#### Sampling with replacement, unequal probabilities
```javascript
var face_name_procedure = {
// timeline parameter hidden to save space ...
timeline_variables: [
{ face: 'person-1.jpg', name: 'Alex' },
{ face: 'person-2.jpg', name: 'Beth' },
{ face: 'person-3.jpg', name: 'Chad' },
{ face: 'person-4.jpg', name: 'Dave' }
],
sample: {
type: 'with-replacement',
size: 10, // 10 trials, with replacement
weights: [3, 1, 1, 1], // The Alex trial is three times as likely to be sampled as the others.
}
}
```
#### Sampling without replacement
```javascript
var face_name_procedure = {
@ -215,7 +233,7 @@ var face_name_procedure = {
],
sample: {
type: 'fixed-repetitions',
size: 3, // 12 trials, 3 of each person, order is randomized.
size: 3, // 3 repetitions of each trial, 12 total trials, order is randomized.
}
}
```

View File

@ -148,7 +148,7 @@ timeline.push(instructions);
type: "text",
text: "Welcome to the experiment. Press any key to begin."
};
timeline.push(welcome_block);
timeline.push(welcome);
/* define instructions trial */
var instructions = {
@ -234,7 +234,7 @@ timeline.push(blue_trial, orange_trial);
type: "text",
text: "Welcome to the experiment. Press any key to begin."
};
timeline.push(welcome_block);
timeline.push(welcome);
/* define instructions trial */
var instructions = {
@ -354,7 +354,7 @@ What happens when the experiment reaches the test procedure? jsPsych will run th
type: "text",
text: "Welcome to the experiment. Press any key to begin."
};
timeline.push(welcome_block);
timeline.push(welcome);
/* define instructions trial */
var instructions = {
@ -454,7 +454,7 @@ var test_procedure = {
type: "text",
text: "Welcome to the experiment. Press any key to begin."
};
timeline.push(welcome_block);
timeline.push(welcome);
/* define instructions trial */
var instructions = {
@ -514,7 +514,7 @@ var test_procedure = {
One aspect of the experiment that could be improved is the duration of the fixation cross. As the experiment stands right now, the timing of the circles appearing is very predictable. We can change that by using a different value for the `timing_response` parameter in the `fixation` trial for each trial. But how can we do that and keep the simple code structure we have now where we only have to define the fixation trial once? One option would be to add another timeline variable, like `"fixation_duration"` and use that to control the timing. But another option is to specify the `timing_response` parameter as a function. If a parameter is a function, jsPsych will execute the function every time the trial runs. That means that if the function returns different results probabilistically, we can get a different parameter value every time the trial runs.
To do that here, we'll use one of the built-in randomization methods in [jsPsych's randomization module](../core_library/jspsych-randomization.md). `jsPsych.randomization.sample()` takes an array of items to sample from and generates a new array of length *N* by sampling either with or without replacement.
To do that here, we'll use one of the built-in randomization methods in [jsPsych's randomization module](../core_library/jspsych-randomization.md). `jsPsych.randomization.sampleWithoutReplacement()` takes an array of items to sample from and generates a new array of length *N* by sampling without replacement.
```javascript
var fixation = {
@ -523,12 +523,12 @@ var fixation = {
is_html: true,
choices: jsPsych.NO_KEYS,
timing_response: function(){
return jsPsych.randomization.sample([250, 500, 750, 1000, 1250, 1500, 1750, 2000], 1)[0];
return jsPsych.randomization.sampleWithoutReplacement([250, 500, 750, 1000, 1250, 1500, 1750, 2000], 1)[0];
}
}
```
In the code above, we replaced the `timing_response: 1000` parameter in `fixation` with a function. Inside the function, we take a sample from the array `[250, 500, 750, 1000, 1250, 1500, 1750, 2000]` of size 1 (second parameter to `jsPsych.randomization.sample`). The return value from calling `jsPsych.randomization.sample` is an array of length 1, so we add the `[0]` selection at the end to get the value out of the array.
In the code above, we replaced the `timing_response: 1000` parameter in `fixation` with a function. Inside the function, we take a sample from the array `[250, 500, 750, 1000, 1250, 1500, 1750, 2000]` of size 1 (second parameter to `jsPsych.randomization.sampleWithoutReplacement`). The return value from calling `jsPsych.randomization.sampleWithoutReplacement` is an array of length 1, so we add the `[0]` selection at the end to get the value out of the array.
### The complete code so far
@ -553,7 +553,7 @@ In the code above, we replaced the `timing_response: 1000` parameter in `fixatio
type: "text",
text: "Welcome to the experiment. Press any key to begin."
};
timeline.push(welcome_block);
timeline.push(welcome);
/* define instructions trial */
var instructions = {
@ -584,7 +584,7 @@ In the code above, we replaced the `timing_response: 1000` parameter in `fixatio
is_html: true,
choices: jsPsych.NO_KEYS,
timing_response: function(){
return jsPsych.randomization.sample([250, 500, 750, 1000, 1250, 1500, 1750, 2000], 1)[0];
return jsPsych.randomization.sampleWithoutReplacement([250, 500, 750, 1000, 1250, 1500, 1750, 2000], 1)[0];
}
}
@ -649,7 +649,7 @@ jsPsych.init({
type: "text",
text: "Welcome to the experiment. Press any key to begin."
};
timeline.push(welcome_block);
timeline.push(welcome);
/* define instructions trial */
var instructions = {
@ -680,7 +680,7 @@ jsPsych.init({
is_html: true,
choices: jsPsych.NO_KEYS,
timing_response: function(){
return jsPsych.randomization.sample([250, 500, 750, 1000, 1250, 1500, 1750, 2000], 1)[0];
return jsPsych.randomization.sampleWithoutReplacement([250, 500, 750, 1000, 1250, 1500, 1750, 2000], 1)[0];
}
}
@ -746,7 +746,7 @@ var fixation = {
is_html: true,
choices: jsPsych.NO_KEYS,
timing_response: function(){
return jsPsych.randomization.sample([250, 500, 750, 1000, 1250, 1500, 1750, 2000], 1)[0];
return jsPsych.randomization.sampleWithoutReplacement([250, 500, 750, 1000, 1250, 1500, 1750, 2000], 1)[0];
},
data: {test_part: 'fixation'}
}
@ -775,7 +775,7 @@ var fixation = {
type: "text",
text: "Welcome to the experiment. Press any key to begin."
};
timeline.push(welcome_block);
timeline.push(welcome);
/* define instructions trial */
var instructions = {
@ -806,7 +806,7 @@ var fixation = {
is_html: true,
choices: jsPsych.NO_KEYS,
timing_response: function(){
return jsPsych.randomization.sample([250, 500, 750, 1000, 1250, 1500, 1750, 2000], 1)[0];
return jsPsych.randomization.sampleWithoutReplacement([250, 500, 750, 1000, 1250, 1500, 1750, 2000], 1)[0];
},
data: {test_part: 'fixation'}
}
@ -885,7 +885,7 @@ The `data.key_press` value is a numeric key code indicating which key the subjec
type: "text",
text: "Welcome to the experiment. Press any key to begin."
};
timeline.push(welcome_block);
timeline.push(welcome);
/* define instructions trial */
var instructions = {
@ -916,7 +916,7 @@ The `data.key_press` value is a numeric key code indicating which key the subjec
is_html: true,
choices: jsPsych.NO_KEYS,
timing_response: function(){
return jsPsych.randomization.sample([250, 500, 750, 1000, 1250, 1500, 1750, 2000], 1)[0];
return jsPsych.randomization.sampleWithoutReplacement([250, 500, 750, 1000, 1250, 1500, 1750, 2000], 1)[0];
},
data: {test_part: 'fixation'}
}
@ -1011,7 +1011,7 @@ This code is available in the examples folder in the jsPsych download. It is cal
type: "text",
text: "Welcome to the experiment. Press any key to begin."
};
timeline.push(welcome_block);
timeline.push(welcome);
/* define instructions trial */
var instructions = {
@ -1043,7 +1043,7 @@ This code is available in the examples folder in the jsPsych download. It is cal
is_html: true,
choices: jsPsych.NO_KEYS,
timing_response: function(){
return jsPsych.randomization.sample([250, 500, 750, 1000, 1250, 1500, 1750, 2000], 1)[0];
return jsPsych.randomization.sampleWithoutReplacement([250, 500, 750, 1000, 1250, 1500, 1750, 2000], 1)[0];
},
data: {test_part: 'fixation'}
}

View File

@ -50,7 +50,7 @@
is_html: true,
choices: jsPsych.NO_KEYS,
timing_response: function(){
return jsPsych.randomization.sample([250, 500, 750, 1000, 1250, 1500, 1750, 2000], 1)[0];
return jsPsych.randomization.sampleWithoutReplacement([250, 500, 750, 1000, 1250, 1500, 1750, 2000], 1)[0];
},
data: {test_part: 'fixation'}
}

View File

@ -43,10 +43,10 @@
order = jsPsych.randomization.shuffle(order);
current_idx = 0;
}
var predictor = jsPsych.randomization.sample(locations, 1)[0];
var predictor = jsPsych.randomization.sampleWithoutReplacement(locations, 1)[0];
if(last_target !== null){
while(predictor[0] == last_target[0] && predictor[1] == last_target[1]){
predictor = jsPsych.randomization.sample(locations, 1)[0];
predictor = jsPsych.randomization.sampleWithoutReplacement(locations, 1)[0];
}
}
last_predictor = predictor;