对于R中的循环返回错误'找不到对象'

时间:2017-03-31 18:18:42

标签: r for-loop

我正在学习R并编写了我的第一个for循环。对于1000次迭代,我创建了4个向量,每个向量具有10,100,1000和10000个维度。这些所谓的theta1值无法识别。我当时尝试运行一个theta1并且它可以工作但是运行所有4会给出错误'找不到对象'。我不清楚这里有什么问题,任何人都可以解释一下吗?

k=1000

'Method1'

for(i in 1:k){
  N10=runif(10) 
  N100=runif(100)
  N1000=runif(1000)
  N10000=runif(10000)
  theta1_10[i]=(1/10)*4*sum(sqrt(1-N10^2))
  theta1_100[i]=(1/100)*4*sum(sqrt(1-N100^2))
  theta1_1000[i]=(1/1000)*4*sum(sqrt(1-N1000^2))
  theta1_10000[i]=(1/10000)*4*sum(sqrt(1-N10000^2))
}

'Result Method 1'
m_theta1_10 = mean(theta1_10)
sd_theta1_10 = sd(theta1_10)
m_theta1_100 = mean(theta1_100)
sd_theta1_100 = sd(theta1_100)
m_theta1_1000 = mean(theta1_1000)
sd_theta1_1000 = sd(theta1_1000)
m_theta1_10000 = mean(theta1_10000)
sd_theta1_10000 = sd(theta1_10000)

2 个答案:

答案 0 :(得分:2)

我写这个答案是因为问题和接受的答案(在编辑之前)都表明R中编程风格不好:他们正在for循环中增长一个载体。 (参见Patrick Burns' The R Inferno Circle 2 。)

从简单的基准测试中,效果将变得清晰。任务是创建一个向量x,其中包含整数1到k

k <- 10000L
microbenchmark::microbenchmark(
  grow = {
    x <- integer(0)
    for (i in seq.int(k)) x <- c(x, i)
    x
  },
  subscript = {
    x <- integer(k)
    for (i in seq.int(k)) x[i] <- i
    x
  },
  colon_operator = {
    x <- 1L:k
    x
  },
  times = 10L
)
#Unit: microseconds
#           expr       min        lq        mean    median        uq        max neval
#           grow 93491.676 96127.568 104219.0140 97123.627 99459.343 165545.063    10
#      subscript  9067.607  9215.996   9483.0962  9551.288  9771.795   9938.307    10
# colon_operator     5.664     7.552      7.9675     8.307     8.685      9.063    10
很明显,即使对于长度为10000的附加元素的小向量,也要比预先分配所需长度慢一些。此处包含冒号运算符的时序,以证明内置向量化函数的好处。

因此,需要重新编写有问题的代码和answer以使用下标来提高效率。

# initialize the random number generator for reproducible results
set.seed(1234L)
# allocate memory for the vectors beforehand
theta1_10 = numeric(k)
theta1_100 = numeric(k)
theta1_1000 = numeric(k)
theta1_10000 = numeric(k)

# Method1
for(i in seq.int(k)){
  N10=runif(10) 
  N100=runif(100)
  N1000=runif(1000)
  N10000=runif(10000)
  # update by subscripting
  theta1_10[i] = (1/10)*4*sum(sqrt(1-N10^2))
  theta1_100[i] = (1/100)*4*sum(sqrt(1-N100^2))
  theta1_1000[i] = (1/1000)*4*sum(sqrt(1-N1000^2))
  theta1_10000[i] = (1/10000)*4*sum(sqrt(1-N10000^2))
}

但是,整个代码可以用更简洁的方式重写:

library(data.table)
set.seed(1234)
k <- 1000L
N <- 10^(1:4)
rbindlist(
  lapply(N, function(i) {
    theta1 <- replicate(k, 4 / i * sum(sqrt(1 - runif(i)^2)))
    data.table(N = i, mean = mean(theta1), sd = sd(theta1))
  }))
#       N     mean         sd
#1:    10 3.144974 0.27238683
#2:   100 3.140716 0.09040696
#3:  1000 3.141791 0.02654225
#4: 10000 3.141585 0.00886737

答案 1 :(得分:1)

您需要在为其指定值之前初始化矢量。 对于这种情况,它是:

SET MYdir=%NewPath%\%CUST%\Product
SET "MYsCount=1"
SET /p MYsCount="Number of MYs in project? (default: %MYSCount%): "
For ($MYsCount = 1; $MYsCount -eq 10; $MYsCount++){
   SET /p MyNums="Enter %%a Product Numbers: " 
   CALL MD "%MYdir%\%CUST%\Product_%%"
} 
SET "$MYsCount="