r语言 - 同一池的两个随机唯一样本



我试图在每个样本中获得两个具有独特元素的样本。也就是说,"first"上的字符串。向量不能在"秒"中。向量。不幸的是,我总是得到重复的字符串,我找不到解决这个问题的方法。我试着用if-else来解决,但是没有成功。

编辑:最终输出应该是成对的。同样的数字应该出现在第二。唯一不同的是字母。每个字母必须出现三次。我不想要重复元素的原因是,当我创建对的时候,我得到的是像1_W和1_W这样的对。这是不可能的。

输出应该是这样的:

first: 12_U, 23_U, 6_U, 8_T, 24_T, 22_T, 7_S, 10_S, 19_S, 21_W, 14_W, 2_W
second: 12_W, 23_W, 6_W, 8_S, 24_S, 22_S, 7_T, 10_T, 19_T, 21_U, 14_U, 2_U

编辑2:

我在解释我需要什么方面做得很糟糕。这段代码将用于为我将要收集数据的研究选择标题。

每个主题代表一个特定主题的标题,例如全球变暖。共有24个主题。每个版本(U, T, S, W)代表一个真正的标题(T)的变化。

我有一个标题库,总共有96个标题,这些标题在主题和版本方面有所不同。1_U是主题1的U版本。我想检查参与者将为每对选择哪些版本。

我需要的是

  1. 选择12个主题;
  2. 在同一主题中创建成对,以便参与者可以在同一标题的两个版本之间进行选择。
  3. 参与者需要始终看到:12对(同一主题的2个版本)。
  4. 我还需要保证他们将看到每个版本的相同比例。这就是为什么我创建了矢量" first "和矢量" second "来满足这个标准。

然而,我得到了重复版本的配对。因此,我得到的一些配对是12_S和12_S,当它们应该是12_S和任何其他版本(12_U, 12_S或12_W)时,因为参与者在主题12的S版本和主题12的S版本之间做出选择是没有意义的。

通过创建两个向量,我能够得到我想要的,除了一些对包含相同的标题。

themes <- c(1:24)
set.seed(1)
twelve <- sample(themes, 12)
versions <- c('U', 'T', 'S', 'W')
set.seed(14) 
first <- sample(paste(sample(twelve), rep(versions, 3), sep='_'))
second <- sample(paste(sample(twelve), rep(versions, 3), sep='_'))
repeated <- first[first %in% second]
if (is.null(repeated)) {
print(second) #if there are no elements in the vector "repeated", then print repeated
} else {
x <- sample(paste(sample(twelve), rep(versions, 3), sep='_')) #otherwise, pick another sample
}

为了确保你得到2个矢量firstsecond,其中first中的主题不存在于second中,你要么需要在矢量中重复主题,要么必须使用采样将主题分开。

set.seed(1)
themes <- 1:24
versions <- c('U', 'T', 'S', 'W')
split_idx <- sample(length(themes), 0.5*length(themes))
set_1 <- themes[split_idx]
set_2 <- themes[-split_idx]

创建2个唯一的样本,由

验证
set_1 %in% set_2

返回一个只有FALSE项的布尔向量。

如果你只想在最后2个向量中使用3个字母,我建议如下:

first <- paste(sample(set_1), sample(versions, 3), sep = "_")
secnd <- paste(sample(set_2), sample(versions, 3), sep = "_")

rep(versions, 3)的使用是不必要的,因为R会在一个向量较短时自动复制。

要获得具有保留这些属性的变化主题的新向量,您必须将主题再次拆分为2组。

编辑1:回答更新后的问题。

生成一个主题示例:

set.seed(1)
themes <- 1:24
versions <- c('U', 'T', 'S', 'W')
theme_sample <- sample(themes, 12)

要使两个向量的版本是随机且不同的,下面的"hacky"我想到了解决办法。

first_versions <- sample(versions)
while(sum((second_versions <- sample(versions)) == first_versions) != 0){}

上面创建了一个示例,然后不断地重新创建第二个示例,直到版本不再重复元素。剩下的就是得到最后的向量

first <- paste(theme_sample, first_versions, sep = "_")
second <- paste(theme_sample, second_versions, sep = "_")

我认为您可以更轻松地对您的配对进行采样(没有重复),然后粘贴您的主题值。因此,我们首先抽样12个主题,然后应用到该列表并粘贴您的成对版本。你得到一个有两行的矩阵和你的对。

set.seed(1)
themes <- 1:24
versions <- c("U", "T", "S", "W")
pairs <- sapply(sample(themes, 12), FUN = function(x) paste(x, sample(versions, 2), sep = "_"))
pairs
#      [,1]  [,2]  [,3]  [,4]  [,5]   [,6]   [,7]   [,8]   [,9]  [,10]  [,11]  [,12]
# [1,] "4_T" "7_S" "1_S" "2_U" "11_U" "14_U" "18_T" "22_T" "5_W" "16_U" "10_T" "6_T"
# [2,] "4_W" "7_U" "1_U" "2_W" "11_T" "14_W" "18_W" "22_U" "5_S" "16_S" "10_W" "6_W"
first <- pairs[1, ]
# [1] "4_T"  "7_S"  "1_S"  "2_U"  "11_U" "14_U" "18_T" "22_T" "5_W"  "16_U" "10_T" "6_T" 
second <- pairs[2, ]
# [1] "4_W"  "7_U"  "1_U"  "2_W"  "11_T" "14_W" "18_W" "22_U" "5_S"  "16_S" "10_W" "6_W"

这里使用蛮力方法。我会为12名参与者选择的两个主题创建两个sampsampleversions用同样的方法。repeat直到每个参与者在两个(即在结果矩阵的每一行)中都没有副本。接下来,使用Mapsamp_vs的行分别复制两次,并将paste的行一起复制。将其封装在函数samp_fun中。

samp_fun <- (themes, versions) {
themes_12 <- sample(themes, 12)
repeat {
samp_th <- replicate(2, sample(themes_12))
samp_vs <- replicate(2, sample(versions))
if (!any(apply(samp_th, 1, duplicated)) &
!any(apply(samp_vs, 1, duplicated))) break
}
samp_vs <- samp_vs[rep(seq_len(nrow(samp_vs)), each=3), ]
Map((...) paste(..., sep='_'),
as.data.frame(samp_th), as.data.frame(samp_vs)) |>
setNames(c('first', 'second'))
}
使用

themes <- 1:24
versions <- c('U', 'T', 'S', 'W')
set.seed(42)
res <- samp_fun(themes, versions)
结果

给出两个组的列表。

res$first
# [1] "4_S"  "15_S" "9_S"  "18_T" "5_T"  "20_T"
# [7] "17_W" "24_W" "8_W"  "7_U"  "1_U"  "10_U"
res$second
# [1] "15_U" "4_U"  "10_U" "8_W"  "7_W"  "24_W"
# [7] "5_S"  "18_S" "1_S"  "17_T" "9_T"  "20_T"

如果你想要first,second在工作区,使用list2env

list2env(res, .GlobalEnv)
first
second

注意:R>= 4.1 .

最新更新