首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >嵌套for loop - mark-recapture

嵌套for loop - mark-recapture
EN

Stack Overflow用户
提问于 2017-08-06 11:20:55
回答 1查看 158关注 0票数 0

感谢您抽出时间阅读这篇文章。

下面的代码创建了一个图表,该图表采用了100个样本,这些样本占总体(400)的5%到15%。

然而,我想要做的是在图表中添加另外两个部分。它看起来像这样:

从1-100个样本中抽取100个样本,这些样本占总体(400)的5%到15%。从101到200,取100个样本,占总人口的5%到15% (800)。从201-300中抽取100个样本,占总人口(300)的5%到15%。

我假设这需要一个嵌套的for循环。有谁有关于如何做到这一点的建议吗?

耽误您时间,实在对不起。柯尔斯腾

代码语言:javascript
复制
N <- 400
pop <- c(1:N)

lower.bound <- round(x = .05 * N, digits = 0)
lower.bound ## Smallest possible sample size

upper.bound <- round(x = .15 * N, digits = 0)
upper.bound ## Largest possible sample size

length.ss.interval <- length(c(lower.bound:upper.bound))
length.ss.interval ## total possible sample sizes, ranging form lower.bound
to upper.bound
sample(x = c(lower.bound:upper.bound),
       size = 1,
       prob = c(rep(1/length.ss.interval, length.ss.interval)))

n.samples <- 100

dat <- matrix(data = NA,
              nrow = length(pop),
              ncol = n.samples + 1)

dat[,1] <- pop

for(i in 2:ncol(dat)) {
  a.sample <- sample(x = pop,
                     size = sample(x = c(lower.bound:upper.bound),
                                   size = 1,
                                   prob = c(rep(1/length.ss.interval,
length.ss.interval))),
                     replace = FALSE)
  dat[,i] <- dat[,1] %in% a.sample
}
schnabel.comp <- data.frame(sample = 1:n.samples,
                            n.sampled = apply(X = dat, MARGIN = 2, FUN =
sum)[2:length(apply(X = dat, MARGIN = 2, FUN = sum))]
)
n.prev.sampled <- c(0, rep(NA, n.samples-1))
n.prev.sampled

n.prev.sampled[2] <- sum(ifelse(test = dat[,3] == 1 & dat[,2] == 1,
                                yes = 1,
                                no = 0))

for(i in 4:ncol(dat)) {
  n.prev.sampled[i-1] <- sum(ifelse(test = dat[,i] == 1 &
rowSums(dat[,2:(i-1)]) > 0,
                                    yes = 1,
                                    no = 0))
}

schnabel.comp$n.prev.sampled <- n.prev.sampled
schnabel.comp$n.newly.sampled <- with(schnabel.comp,
                                      n.sampled - n.prev.sampled)
schnabel.comp$cum.sampled <- c(0,
cumsum(schnabel.comp$n.newly.sampled)[2:n.samples-1])
schnabel.comp$numerator <- with(schnabel.comp,
                                n.sampled * cum.sampled)
schnabel.comp$pop.estimate <- NA

for(i in 1:length(schnabel.comp$pop.estimate)) {
  schnabel.comp$pop.estimate[i] <- sum(schnabel.comp$numerator[1:i]) /
sum(schnabel.comp$n.prev.sampled[1:i])
}

if (!require("ggplot2")) {install.packages("ggplot2"); require("ggplot2")}
if (!require("scales")) {install.packages("scales"); require("scales")}


small.sample.dat <- schnabel.comp

small.sample <- ggplot(data = small.sample.dat,
                       mapping = aes(x = sample, y = pop.estimate)) +
  geom_point(size = 2) +
  geom_line() +
  geom_hline(yintercept = N, col = "red", lwd = 1) +
  coord_cartesian(xlim = c(0:100), ylim = c(300:500)) +
  scale_x_continuous(breaks = pretty_breaks(11)) +
  scale_y_continuous(breaks = pretty_breaks(11)) +
  labs(x = "\nSample", y = "Population estimate\n",
       title = "Sample sizes are between 5% and 15%\nof the population") +
  theme_bw(base_size = 12) +
  theme(aspect.ratio = 1)

我的想法是使用以下代码创建一个嵌套的ifelse语句:

代码语言:javascript
复制
N.2 <- 800
N.3 <- 300
pop.2 <- c(401:N.2)
pop.3 <- c(801:N)

lower.bound.2 <- round(x = .05 * N.2, digits = 0)
upper.bound.2 <- round(x = .15 * N.2, digits = 0)

lower.bound.3 <- round(x = .05 * N.3, digits = 0)
upper.bound.3 <- round(x = .15 * N.3, digits = 0)

也许是某种排列...

代码语言:javascript
复制
dat <- imatrix(ifelse(n.samples ,= 100),
              yes = nrow = length(pop),
              no = ifelse(n.samples > 100 & > 201),
              yes = nrow = length(pop.2),
              no = nrow = length(pop.3),
              ncol = n.samples + 1)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-06 15:49:39

这是你想要的吗?我在下面编写的函数mark_recapture接受四个参数(样本数量、样本的上下限和总体大小),并输出一个矩阵,其中行表示总体中的个体,列表示样本。如果一个人在给定的样本中被捕获,它的得分为1,否则它的得分为0。定义该函数后,您只需使用3种不同的总体大小运行3次,即可得到3种不同的矩阵。

代码语言:javascript
复制
# define variables
num_samp <- 100
lower_sampsize <- 0.05
upper_sampsize <- 0.15

# define sampling function that outputs matrix
mark_recapture <- function (num_samp, pop_size, lower_sampsize, upper_sampsize) {

    # empty matrix
    mat <- matrix(0, pop_size, num_samp)

    # min and max sample size
    min <- ceiling(lower_sampsize*pop_size)
    max <- floor(upper_sampsize*pop_size)

    # vector of random sample sizes between min and max
    samp_sizes <- sample(min:max, num_samp, replace=TRUE)

    # draw the samples and fill in the matrix
    for (i in 1:num_samp) {mat[sample(1:pop_size, samp_sizes[i]),i] <- 1}

    # return matrix
    return(mat)
}

# do the sampling from the 3 populations
mat1 <- mark_recapture(num_samp=num_samp, pop_size=400, lower_sampsize=lower_sampsize, upper_sampsize=upper_sampsize)
mat2 <- mark_recapture(num_samp=num_samp, pop_size=800, lower_sampsize=lower_sampsize, upper_sampsize=upper_sampsize)
mat3 <- mark_recapture(num_samp=num_samp, pop_size=300, lower_sampsize=lower_sampsize, upper_sampsize=upper_sampsize)

虽然这超出了这个问题的范围,但我只想提一下,有专门的R包来分析和模拟标记重新捕获数据,例如multimark。只需搜索"CRAN mark recapture“,你就会找到许多选项。我建议仔细阅读这些内容,仔细考虑您在这里试图实现的目标,因为您可能正在尝试重新发明轮子。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45528244

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档