用于心理学研究的R语言条件下的“随机”排序

x7rlezfr  于 2023-09-27  发布在  R语言
关注(0)|答案(2)|浏览(316)

在我的心理学实验中,我有一个词刺激的配价类别。
1 =负极,2 =中性,3 =正极
我需要用伪随机条件对成千上万的刺激进行排序。
瓦尔_Category在一行中不能有2个以上的相同效价刺激,即连续不超过2次负刺激。
例如-2,2,2 =不可接受
2、2、1 =正常
我无法对数据进行排序。决定整个实验的结果是1,3,2,3,1,3,2,3,2,2,1因为我不允许有一个模式。
我尝试了各种软件包,如dylpr,样品,订单,排序和没有任何到目前为止解决问题。

oknwwptz

oknwwptz1#

我认为有一千种方法可以做到这一点,没有一种可能是非常漂亮的。我写了一个小函数来处理排序。这是一个有点黑客,但它似乎为我所尝试的工作。
为了解释我所做的,该函数的工作原理如下:
1.取化合价的向量和样本。
1.如果发现序列大于所需长度,则(对于每个这样的序列),取该序列在“其他地方”的最后一个值。
1.检查问题是否解决。如果是,返回重新排序的向量。如果没有,那就回到2。

  1. # some vector of valences
  2. val <- rep(1:3,each=50)
  3. pseudoRandomize <- function(x, n){
  4. # take an initial sample
  5. out <- sample(val)
  6. # check if the sample is "bad" (containing sequences longer than n)
  7. bad.seq <- any(rle(out)$lengths > n)
  8. # length of the whole sample
  9. l0 <- length(out)
  10. while(bad.seq){
  11. # get lengths of all subsequences
  12. l1 <- rle(out)$lengths
  13. # find the bad ones
  14. ind <- l1 > n
  15. # take the last value of each bad sequence, and...
  16. for(i in cumsum(l1)[ind]){
  17. # take it out of the original sample
  18. tmp <- out[-i]
  19. # pick new position at random
  20. pos <- sample(2:(l0-2),1)
  21. # put the value back into the sample at the new position
  22. out <- c(tmp[1:(pos-1)],out[i],tmp[pos:(l0-1)])
  23. }
  24. # check if bad sequences (still) exist
  25. # if TRUE, then 'while' continues; if FALSE, then it doesn't
  26. bad.seq <- any(rle(out)$lengths > n)
  27. }
  28. # return the reordered sequence
  29. out
  30. }

示例:

该函数可用于带或不带名称的向量。如果向量被命名,则这些名称将仍然存在于伪随机化向量上。

  1. # simple unnamed vector
  2. val <- rep(1:3,each=5)
  3. pseudoRandomize(val, 2)
  4. # gives:
  5. # [1] 1 3 2 1 2 3 3 2 1 2 1 3 3 1 2
  6. # when names assigned to the vector
  7. names(val) <- 1:length(val)
  8. pseudoRandomize(val, 2)
  9. # gives (first row shows the names):
  10. # 1 13 9 7 3 11 15 8 10 5 12 14 6 4 2
  11. # 1 3 2 2 1 3 3 2 2 1 3 3 2 1 1

此属性可用于随机化整个 Dataframe 。为了实现这一点,从 Dataframe 中取出“价”向量,并通过行索引(1:nrow(dat))或行名称(rownames(dat))为其分配名称。

  1. # reorder a data.frame using a named vector
  2. dat <- data.frame(val=rep(1:3,each=5), stim=rep(letters[1:5],3))
  3. val <- dat$val
  4. names(val) <- 1:nrow(dat)
  5. new.val <- pseudoRandomize(val, 2)
  6. new.dat <- dat[as.integer(names(new.val)),]
  7. # gives:
  8. # val stim
  9. # 5 1 e
  10. # 2 1 b
  11. # 9 2 d
  12. # 6 2 a
  13. # 3 1 c
  14. # 15 3 e
  15. # ...
展开查看全部
dm7nw8vv

dm7nw8vv2#

我相信这个循环会适当地设置化合价类别。我把化合价分类称为治疗。

  1. #Generate example data
  2. s1 = data.frame(id=c(1:10),treat=NA)
  3. #Setting the first two rows
  4. s1[1,"treat"] <- sample(1:3,1)
  5. s1[2,"treat"] <- sample(1:3,1)
  6. #Looping through the remainder of the rows
  7. for (i in 3:length(s1$id))
  8. {
  9. s1[i,"treat"] <- sample(1:3,1)
  10. #Check if the treat value is equal to the previous two values.
  11. if (s1[i,"treat"]==s1[i-1,"treat"] & s1[i-1,"treat"]==s1[i-2,"treat"])
  12. #If so draw one of the values not equal to that value
  13. {
  14. a = 1:3
  15. remove <- s1[i,"treat"]
  16. a=a[!a==remove]
  17. s1[i,"treat"] <- sample(a,1)
  18. }
  19. }

这个解决方案并不是特别优雅。可能有一个更快的方法来完成这一点,通过排序几列或其他东西。

展开查看全部

相关问题