J'écris du code pour générer des conceptions expérimentales équilibrées pour des études de marché, spécifiquement pour une utilisation dans l'analyse conjointe et l'échelle de différence maximale.Randomiser des conceptions expérimentales équilibrées
La première étape consiste à générer une conception de bloc incomplet partiellement équilibré (PBIB). Ceci est simple en utilisant le paquet R AlgDesign
.
Pour la plupart des types de recherche, une telle conception serait suffisante. Cependant, dans l'étude de marché, on veut contrôler les effets d'ordre dans chaque bloc. C'est là que j'apprécierais de l'aide.
Créer des données de test
# The following code is not essential in understanding the problem,
# but I provide it in case you are curious about the origin of the data itself.
#library(AlgDesign)
#set.seed(12345)
#choices <- 4
#nAttributes <- 7
#blocksize <- 7
#bsize <- rep(choices, blocksize)
#PBIB <- optBlock(~., withinData=factor(1:nAttributes), blocksizes=bsize)
#df <- data.frame(t(array(PBIB$rows, dim=c(choices, blocksize))))
#colnames(df) <- paste("Item", 1:choices, sep="")
#rownames(df) <- paste("Set", 1:nAttributes, sep="")
df <- structure(list(
Item1 = c(1, 2, 1, 3, 1, 1, 2),
Item2 = c(4, 4, 2, 5, 3, 2, 3),
Item3 = c(5, 6, 5, 6, 4, 3, 4),
Item4 = c(7, 7, 6, 7, 6, 7, 5)),
.Names = c("Item1", "Item2", "Item3", "Item4"),
row.names = c("Set1", "Set2", "Set3", "Set4", "Set5", "Set6", "Set7"),
class = "data.frame")
** Définir deux fonctions d'aide
balanceMatrix
calcule l'équilibre de la matrice:
balanceMatrix <- function(x){
t(sapply(unique(unlist(x)), function(i)colSums(x==i)))
}
balanceScore
calcule une mesure de 'ajustement' - les scores les plus bas sont meilleurs, avec zéro parfait:
balanceScore <- function(x){
sum((1-x)^2)
}
définir une fonction qui rééchantillonne les rangées au hasard
findBalance <- function(x, nrepeat=100){
df <- x
minw <- Inf
for (n in 1:nrepeat){
for (i in 1:nrow(x)){df[i,] <- sample(df[i, ])}
w <- balanceMatrix(df)
sumw <- balanceScore(w)
if(sumw < minw){
dfbest <- df
minw <- sumw
}
}
dfbest
}
Main code
La trame de données df
est une conception équilibrée de 7 ensembles. Chaque ensemble affichera 4 éléments au répondant. Les valeurs numériques dans df
se réfère à 7 attributs différents. Par exemple, dans Set1, on demandera au répondant de choisir son option préférée parmi les attributs 1, 3, 4 et 7.
L'ordre des éléments dans chaque ensemble n'est conceptuellement pas important. Ainsi un ordre de (1,4,5,7) est identique à (7,5,4,1). Cependant, pour obtenir une conception entièrement équilibrée, chaque attribut apparaîtra un nombre égal de fois dans chaque colonne. Cette conception est là déséquilibrés, puisque l'attribut 1 apparaît 4 fois dans la colonne 1:
df
Item1 Item2 Item3 Item4
Set1 1 4 5 7
Set2 2 4 6 7
Set3 1 2 5 6
Set4 3 5 6 7
Set5 1 3 4 6
Set6 1 2 3 7
Set7 2 3 4 5
Pour essayer de trouver une conception plus équilibrée, je l'ai écrit la fonction findBalance
. Cela conduit à une recherche aléatoire de meilleures solutions, en échantillonnant de manière aléatoire sur les lignes df
. Avec 100 répétitions, il trouve la solution mieux suivante:
set.seed(12345)
dfbest <- findBalance(df, nrepeat=100)
dfbest
Item1 Item2 Item3 Item4
Set1 7 5 1 4
Set2 6 7 4 2
Set3 2 1 5 6
Set4 5 6 7 3
Set5 3 1 6 4
Set6 7 2 3 1
Set7 4 3 2 5
Cela semble plus équilibré, et la matrice de l'équilibre calculé contient beaucoup d'autres. La matrice de solde compte le nombre de fois que chaque attribut apparaît dans chaque colonne.Par exemple, le tableau suivant indique (dans la cellule supérieure gauche) cet attribut 1 apparaît deux fois pas du tout dans la colonne 1, et deux fois dans la colonne 2:
balanceMatrix(dfbest)
Item1 Item2 Item3 Item4
[1,] 0 2 1 1
[2,] 1 1 1 1
[3,] 1 1 1 1
[4,] 1 0 1 2
[5,] 1 1 1 1
[6,] 1 1 1 1
[7,] 2 1 1 0
Le solde score de pour cette solution est 6 , ce qui indique qu'il ya au moins six cellules inégales à 1:
balanceScore(balanceMatrix(dfbest))
[1] 6
Ma question
Merci de suivre cet exemple détaillé. Ma question est comment puis-je réécrire cette fonction de recherche pour être plus systématique? Je voudrais dire R à:
- Réduire au minimum
balanceScore(df)
- En changeant ligne ordre de
df
- Sous réserve: déjà complètement contraint
+1 Ceci est génial. Je vous remercie. – Andrie