简体   繁体   English

如何将此 for 循环的结果保存为向量而不是单个值(在 R 中)?

[英]How do I save the results of this for loop as a vector rather than as a single value (in R)?

I am new to for-loops and am having trouble saving the results of a for loop in the way that I want.我是 for 循环的新手,无法以我想要的方式保存 for 循环的结果。

The loop I'm currently running looks like this:我当前正在运行的循环如下所示:

# Setup objects
n = 100
R = (1:1000)
P = seq(-.9, .9, .1)
betahat_OLS = rep(NA, 1000)
Bhat_OLS = rep(NA, 19)

# Calculate betahat_OLS for each p in P and each r in R
for (p in P) {
  for (r in R) {
    # Simulate data
    v = rnorm(n)
    e = rnorm(n)
    z = rnorm(n)
    u = p*v+e
    x = z+v
    y = 0*x+u
    #Calculate betahat_OLS
    betahat_OLS[r] = sum(x*y)/sum(x^2)
  }
  #Calculate Bhat_OLS
  Bhat_OLS = sum(betahat_OLS)/1000-0
}

# Make a scatterplot with p on the x-axis and Bhat_OLS on the y-axis
plot(P, Bhat_OLS)

The loop seems to be working correctly, except for the fact that I would like to end up with 19 values of Bhat_OLS and only currently get 1 value.循环似乎工作正常,除了我想最终得到 19 个 Bhat_OLS 值并且目前只得到 1 个值。 I want to have a Bhat_OLS value for each value of p in P so that I can plot Bhat_OLS against p;我想为 P 中的每个 p 值都有一个 Bhat_OLS 值,以便我可以针对 p 进行 plot Bhat_OLS; I just don't know how to tell R to do that.我只是不知道如何告诉 R 这样做。

Any help would be greatly appreciated!任何帮助将不胜感激!

You can write your results into a data frame with two columns, containing P and Bhat_OLS .您可以将结果写入具有两列的数据框中,其中包含PBhat_OLS

# Setup objects
n = 100
R = (1:1000)
P = seq(-.9, .9, .1)
betahat_OLS = rep(NA, 1000)
Bhat_OLS = rep(NA, 19)

# initialize result data frame
results <- data.frame(matrix(ncol = 2, nrow = 0, 
                      dimnames = list(NULL, c("P", "Bhat_OLS"))))

# Calculate betahat_OLS for each p in P and each r in R
for (p in P) {
    for (r in R) {
        # Simulate data
        v = rnorm(n)
        e = rnorm(n)
        z = rnorm(n)
        u = p*v+e
        x = z+v
        y = 0*x+u
        #Calculate betahat_OLS
        betahat_OLS = sum(x*y)/sum(x^2)
    }
    #Calculate Bhat_OLS
    Bhat_OLS = sum(betahat_OLS)/1000-0
    
    # insert P and Bhat_OLS into results
    results[nrow(results) + 1,] = c(p, Bhat_OLS)
}

# Make a scatterplot with p on the x-axis and Bhat_OLS on the y-axis
plot(results$P, results$Bhat_OLS)

The fact that you loop over the probabilities makes it difficult with the indices.您循环概率的事实使索引变得困难。 You could loop over seq(P) instead and subset P[i] .您可以循环遍历seq(P)和子集P[i] Also, at the end you need Bhat_OLS[i] .此外,最后你需要Bhat_OLS[i] Then it works.然后它工作。

# Setup objects
n <- 100
R <- (1:1000)
P <- seq(-.9, .9, .1)
betahat_OLS <- rep(NA, length(R))
Bhat_OLS <- rep(NA, length(P))

set.seed(42)  ## for sake of reproducibility

# Calculate betahat_OLS for each p in P and each r in R
for (i in seq(P)) {
  for (r in R) {
    # Simulate data
    v <- rnorm(n)
    e <- rnorm(n)
    z <- rnorm(n)
    u <- P[i]*v + e
    x <- z + v
    y <- 0*x + u
    #Calculate betahat_OLS
    betahat_OLS[r] <- sum(x*y)/sum(x^2)
  }
  #Calculate Bhat_OLS
  Bhat_OLS[i] <- sum(betahat_OLS)/1000 - 0
}

# Make a scatterplot with p on the x-axis and Bhat_OLS on the y-axis
plot(P, Bhat_OLS, xlim=c(-1, 1))

在此处输入图像描述

Alternative solution vapply替代解决方案vapply

In a more R-ish way (right now it is more c-ish) you could define the simulation in a function sim() and use vapply for the outer loop.以更 R-ish 的方式(现在它更 C-ish),您可以在 function sim()中定义模拟,并将vapply用于外部循环。 (Actually also for the inner loop, but I've tested it and this way it's faster.) (实际上也适用于内部循环,但我已经对其进行了测试,这样它会更快。)

sim <- \(p, n=100, R=1:1000) {
  r <- rep(NA, max(R))
  for (i in R) {
    v <- rnorm(n)
    e <- rnorm(n)
    z <- rnorm(n)
    u <- p*v + e
    x <- z + v
    y <- 0*x + u
    r[i] <- sum(x*y)/sum(x^2)
  }
  return(sum(r/1000 - 0))
}

set.seed(42)
Bhat_OLS1 <- vapply(seq(-.9, .9, .1), \(p) sim(p), 0)

stopifnot(all.equal(Bhat_OLS, Bhat_OLS1))

Note:笔记:

R.version.string
# [1] "R version 4.1.2 (2021-11-01)"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM