Generate all unique permutations and convert to data frame
# Loading necessary libraries
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.2 ✔ tibble 3.3.0
## ✔ lubridate 1.9.4 ✔ tidyr 1.3.1
## ✔ purrr 1.0.4
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(combinat)
##
## Attaching package: 'combinat'
##
## The following object is masked from 'package:utils':
##
## combn
# Setting seed for reproducibility
set.seed(1234)
# Defining the conditions
conditions <- c("NS", "S", "SN")
# Generating all unique permutations
perm_unique <- permn(conditions)
# Converting the list of permutations to a transposed dataframe and naming columns
perm_df <- map_dfr(perm_unique, ~as.data.frame(t(.x))) %>%
rename_with(~paste0("condition_", seq_along(.))) %>%
mutate(permutation = row_number()) %>%
select(permutation, contains("condition"))
# Viewing the generated permutations
print(perm_df)
## permutation condition_1 condition_2 condition_3
## 1 1 NS S SN
## 2 2 NS SN S
## 3 3 SN NS S
## 4 4 SN S NS
## 5 5 S SN NS
## 6 6 S NS SN
Randomize the Order of the Rows (Permutations)
# Randomizing the order of the rows (permutations)
perm_random <- perm_df %>%
slice_sample(n = nrow(perm_df)) %>%
mutate(participant = row_number()) %>%
select(participant, contains("condition"))
# Viewing the randomized permutations
print(perm_random)
## participant condition_1 condition_2 condition_3
## 1 1 SN S NS
## 2 2 NS SN S
## 3 3 S SN NS
## 4 4 NS S SN
## 5 5 S NS SN
## 6 6 SN NS S
Assigning 30 (fully counterbalanced) Participants to the Randomised
Sequences
# Number of participants
n_participants <- 30
# Number of unique sequences generated (6 permutations)
n_sequences <- nrow(perm_df)
# Verify the number of sequences
print(n_sequences)
## [1] 6
# Randomly assigning participants to sequences
assignments <- sample(rep(1:n_sequences, each = n_participants / n_sequences))
# Creating the final dataframe with assignments
final_assignments <- data.frame(
Participant = 1:n_participants,
Sequence = assignments,
Condition1 = perm_random[assignments, "condition_1"],
Condition2 = perm_random[assignments, "condition_2"],
Condition3 = perm_random[assignments, "condition_3"]
)
# Viewing the final assignments
print(final_assignments)
## Participant Sequence Condition1 Condition2 Condition3
## 1 1 2 NS SN S
## 2 2 1 SN S NS
## 3 3 2 NS SN S
## 4 4 4 NS S SN
## 5 5 1 SN S NS
## 6 6 1 SN S NS
## 7 7 2 NS SN S
## 8 8 5 S NS SN
## 9 9 6 SN NS S
## 10 10 3 S SN NS
## 11 11 3 S SN NS
## 12 12 4 NS S SN
## 13 13 6 SN NS S
## 14 14 4 NS S SN
## 15 15 6 SN NS S
## 16 16 2 NS SN S
## 17 17 4 NS S SN
## 18 18 5 S NS SN
## 19 19 1 SN S NS
## 20 20 4 NS S SN
## 21 21 2 NS SN S
## 22 22 6 SN NS S
## 23 23 5 S NS SN
## 24 24 5 S NS SN
## 25 25 3 S SN NS
## 26 26 3 S SN NS
## 27 27 6 SN NS S
## 28 28 5 S NS SN
## 29 29 1 SN S NS
## 30 30 3 S SN NS
LS0tCnRpdGxlOiAiUEVBVCBQcm9qZWN0OiBSYW5kb21pc2F0aW9uIFByb2Nlc3MiCmF1dGhvcjogIkxheWFuIEZlc3NsZXIiCmRhdGU6ICIyMDI1LTA5LTE3IgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIGVkaXRvcl9vcHRpb25zOiBudWxsCiAgbWFya2Rvd246CiAgICB3cmFwOiBzZW50ZW5jZQogIHdvcmRfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKLS0tCgoKIyBHZW5lcmF0ZSBhbGwgdW5pcXVlIHBlcm11dGF0aW9ucyBhbmQgY29udmVydCB0byBkYXRhIGZyYW1lIApgYGB7cn0KIyBMb2FkaW5nIG5lY2Vzc2FyeSBsaWJyYXJpZXMKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoY29tYmluYXQpCgojIFNldHRpbmcgc2VlZCBmb3IgcmVwcm9kdWNpYmlsaXR5CnNldC5zZWVkKDEyMzQpCgojIERlZmluaW5nIHRoZSBjb25kaXRpb25zCmNvbmRpdGlvbnMgPC0gYygiTlMiLCAiUyIsICJTTiIpCgojIEdlbmVyYXRpbmcgYWxsIHVuaXF1ZSBwZXJtdXRhdGlvbnMKcGVybV91bmlxdWUgPC0gcGVybW4oY29uZGl0aW9ucykKCiMgQ29udmVydGluZyB0aGUgbGlzdCBvZiBwZXJtdXRhdGlvbnMgdG8gYSB0cmFuc3Bvc2VkIGRhdGFmcmFtZSBhbmQgbmFtaW5nIGNvbHVtbnMKcGVybV9kZiA8LSBtYXBfZGZyKHBlcm1fdW5pcXVlLCB+YXMuZGF0YS5mcmFtZSh0KC54KSkpICU+JQogIHJlbmFtZV93aXRoKH5wYXN0ZTAoImNvbmRpdGlvbl8iLCBzZXFfYWxvbmcoLikpKSAlPiUKICBtdXRhdGUocGVybXV0YXRpb24gPSByb3dfbnVtYmVyKCkpICU+JQogIHNlbGVjdChwZXJtdXRhdGlvbiwgY29udGFpbnMoImNvbmRpdGlvbiIpKQoKIyBWaWV3aW5nIHRoZSBnZW5lcmF0ZWQgcGVybXV0YXRpb25zCnByaW50KHBlcm1fZGYpCgpgYGAKIyBSYW5kb21pemUgdGhlIE9yZGVyIG9mIHRoZSBSb3dzIChQZXJtdXRhdGlvbnMpCmBgYHtyfQojIFJhbmRvbWl6aW5nIHRoZSBvcmRlciBvZiB0aGUgcm93cyAocGVybXV0YXRpb25zKQpwZXJtX3JhbmRvbSA8LSBwZXJtX2RmICU+JQogIHNsaWNlX3NhbXBsZShuID0gbnJvdyhwZXJtX2RmKSkgJT4lCiAgbXV0YXRlKHBhcnRpY2lwYW50ID0gcm93X251bWJlcigpKSAlPiUKICBzZWxlY3QocGFydGljaXBhbnQsIGNvbnRhaW5zKCJjb25kaXRpb24iKSkKCiMgVmlld2luZyB0aGUgcmFuZG9taXplZCBwZXJtdXRhdGlvbnMKcHJpbnQocGVybV9yYW5kb20pCmBgYAoKIyBBc3NpZ25pbmcgMzAgKGZ1bGx5IGNvdW50ZXJiYWxhbmNlZCkgUGFydGljaXBhbnRzIHRvIHRoZSBSYW5kb21pc2VkIFNlcXVlbmNlcwpgYGB7cn0KIyBOdW1iZXIgb2YgcGFydGljaXBhbnRzCm5fcGFydGljaXBhbnRzIDwtIDMwCgojIE51bWJlciBvZiB1bmlxdWUgc2VxdWVuY2VzIGdlbmVyYXRlZCAoNiBwZXJtdXRhdGlvbnMpCm5fc2VxdWVuY2VzIDwtIG5yb3cocGVybV9kZikKCiMgVmVyaWZ5IHRoZSBudW1iZXIgb2Ygc2VxdWVuY2VzCnByaW50KG5fc2VxdWVuY2VzKQoKIyBSYW5kb21seSBhc3NpZ25pbmcgcGFydGljaXBhbnRzIHRvIHNlcXVlbmNlcwphc3NpZ25tZW50cyA8LSBzYW1wbGUocmVwKDE6bl9zZXF1ZW5jZXMsIGVhY2ggPSBuX3BhcnRpY2lwYW50cyAvIG5fc2VxdWVuY2VzKSkKCiMgQ3JlYXRpbmcgdGhlIGZpbmFsIGRhdGFmcmFtZSB3aXRoIGFzc2lnbm1lbnRzCmZpbmFsX2Fzc2lnbm1lbnRzIDwtIGRhdGEuZnJhbWUoCiAgUGFydGljaXBhbnQgPSAxOm5fcGFydGljaXBhbnRzLAogIFNlcXVlbmNlID0gYXNzaWdubWVudHMsCiAgQ29uZGl0aW9uMSA9IHBlcm1fcmFuZG9tW2Fzc2lnbm1lbnRzLCAiY29uZGl0aW9uXzEiXSwKICBDb25kaXRpb24yID0gcGVybV9yYW5kb21bYXNzaWdubWVudHMsICJjb25kaXRpb25fMiJdLAogIENvbmRpdGlvbjMgPSBwZXJtX3JhbmRvbVthc3NpZ25tZW50cywgImNvbmRpdGlvbl8zIl0KKQoKIyBWaWV3aW5nIHRoZSBmaW5hbCBhc3NpZ25tZW50cwpwcmludChmaW5hbF9hc3NpZ25tZW50cykKYGBgCgoK