首页 > 解决方案 > 在 R 的循环中使用开始值和结束值进行采样

问题描述

我试图在一系列值之间进行采样,作为 R 中较大循环的一部分。随着循环进行到每一行j,我想在start列中给出的值和列中给出的值之间采样一个数字end,放置sampled该行的列中的值。

结果应如下所示:

ID  start  end  sampled
a   25     67   44
b   36     97   67
c   23     85   77
d   15     67   52
e   21     52   41
f   43     72   66
g   39     55   49
h   27     62   35
i   11     99   17
j   21     89   66
k   28     65   48
l   44     58   48
m   16     77   22
n   25     88   65

我开始使用mapply,它对整个 df 进行采样,但随后我尝试将所有 15 个采样值放入一行。

df[j,4] <- mapply(function(x, y) sample(seq(x, y), 1), df$start, df$end)

我想也许使用的东西seq可能会起作用,但这会导致错误说它from的长度必须为 1。

df[j,4] <- sample(seq(df$start, df$end),1,replace=TRUE)

外部循环结构非常复杂,所以我没有在这里包含它,但是df[j,4]代码的一部分是必要的,因为它是更大循环的一部分。在某些情况下,必须根据实际数据集中的其他依赖项对行进行重新采样。例如, 的采样值a可能需要大于b。其余代码更新采样列,检查依赖关系,如果不满足依赖关系,将重新运行示例。如果我能让这个采样部分正常工作,我应该能够毫不费力地插入它(我希望如此)。

这是一个示例数据集。

structure(list(ID = c("a", "b", "c", "d", "e", "f", "g", "h", 
"i", "j", "k", "l", "m", "n"), start = c(25, 36, 23, 15, 21, 
43, 39, 27, 11, 21, 28, 44, 16, 25), end = c(67, 97, 85, 67, 
52, 72, 55, 62, 99, 89, 65, 58, 77, 88), sampled = c(NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)), class = c("spec_tbl_df", 
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -14L), spec = structure(list(
    cols = list(ID = structure(list(), class = c("collector_character", 
    "collector")), start = structure(list(), class = c("collector_double", 
    "collector")), end = structure(list(), class = c("collector_double", 
    "collector")), sampled = structure(list(), class = c("collector_logical", 
    "collector"))), default = structure(list(), class = c("collector_guess", 
    "collector")), skip = 1), class = "col_spec"))```

标签: rloopssampleseqmapply

解决方案


首先,将数据以更易于使用的格式放入dput(df)

df <- structure(list(ID = structure(1:14, .Label = c("a", "b", "c", 
    "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n"), class = "factor"), 
    start = c(25L, 36L, 23L, 15L, 21L, 43L, 39L, 27L, 11L, 21L, 
    28L, 44L, 16L, 25L), end = c(67L, 97L, 85L, 67L, 52L, 72L, 
    55L, 62L, 99L, 89L, 65L, 58L, 77L, 88L), sampled = c(44L, 
    67L, 77L, 52L, 41L, 66L, 49L, 35L, 17L, 66L, 48L, 48L, 22L, 
    65L)), class = "data.frame", row.names = c(NA, -14L))

你非常接近,mapply()但你让它变得比它需要的更难:

df$sampled <- mapply(function(x, y) sample(seq(x, y), 1), df$start, df$end)
df
#    ID start end sampled
# 1   a    25  67      67
# 2   b    36  97      86
# 3   c    23  85      54
# 4   d    15  67      36
# 5   e    21  52      37
# 6   f    43  72      60
# 7   g    39  55      44
# 8   h    27  62      37
# 9   i    11  99      86
# 10  j    21  89      52
# 11  k    28  65      65
# 12  l    44  58      51
# 13  m    16  77      62
# 14  n    25  88      31

推荐阅读