R 使用非顺序向量作为循环的输入
我在R中遇到了一些循环函数的问题,在这个网站上找不到关于这个问题的答案。我想使用一个数值向量作为R中循环的输入 例如:R 使用非顺序向量作为循环的输入,r,loops,vector,R,Loops,Vector,我在R中遇到了一些循环函数的问题,在这个网站上找不到关于这个问题的答案。我想使用一个数值向量作为R中循环的输入 例如: ns <- c(10, 20, 40, 80, 160) for (n in ns) { ni[n] <- round(rnorm(1, mean = n, sd = 1)) } ns记住R中的许多函数都是矢量化的 > rnorm(length(ns), mean=ns) [1] 9.905652 19.721717 40.462751 78.
ns <- c(10, 20, 40, 80, 160)
for (n in ns) {
ni[n] <- round(rnorm(1, mean = n, sd = 1))
}
ns记住R中的许多函数都是矢量化的
> rnorm(length(ns), mean=ns)
[1] 9.905652 19.721717 40.462751 78.982971 160.770257
(在您的问题中,ni[n]
创建一个向量,长度等于n
的最大值,即160个元素)
从@VictorK提供的sapply
解决方案中可以看出这一点很有趣
sapply(ns, function(n) round(rnorm(1, mean = n, sd = 1)))
计算出四舍五入
并删除默认参数sd=1
,因此
round(sapply(ns, function(n) rnorm(1, mean = n)))
然后认识到rnorm
可以替换匿名函数function(n)…
,如果我们在sapply
调用中将其命名为第一个参数。rnorm
的第一个参数名为n
,因此有些混乱;但是我们正在强制ns
的元素匹配第二个参数mean
。例如,我们第一次通过sapply评估rnorm(ns[[1]],n=1)
。R首先按名称匹配参数,因此n=1匹配rnorm
的第一个参数,然后按剩余参数中的位置匹配,因此未命名参数ns[[1]
匹配下一个可用参数mean
)
然后也许我们看到了完全矢量化的解
round(rnorm(n = length(ns), mean = ns))
有几种方法可以动态创建向量。以下是一些选项:
1) 使用循环(但请参阅下一个解决方案,因为您应该尽量避免在R中使用循环):
第二个是惯用的R.@Martin Morgan为您给出的特定示例演示了如何正确执行此操作。但是,我们假设您想要使用一个未矢量化的函数,或者您想要按照实际示例的思路做其他事情
一种方法是迭代ns
元素的索引,而不是元素本身。考虑
ns <- c(10, 20, 40, 80, 160)
ni <- numeric(length = length(ns)) ## pre-allocate storage
for (n in seq_along(ns)) {
ni[n] <- round(rnorm(1, mean = ns[n], sd = 1))
}
> ni
[1] 12 21 40 80 160
ns在编码时遇到了一个类似的问题。所以我想我会给出一个更干净的循环版本。我个人会使用以下结构:
ns <- c(10, 20, 40, 80, 160)
ni <- numeric(length = length(ns)) # keeping this as per Victor's earlier post#
y=0 #adding starting counter#
for (i in ns) { # ns is already defined with its numeric sequence on line 1 of the
# code #
y=y+1 # counter used in the ni vector
ni[[y]] <- meanX(i) # preferable to create a custom function but not mandatory
}
ni # will produce only the 5 outputs of the rnorm function
# 11 21 41 81 161
## Custom function ##
meanX <-function(meanX) {round(rnorm(1, mean = meanX, sd = 1))
return(round(rnorm(1, mean = meanX, sd = 1)))
}
## end of Custom function ##
ns您指出要避免R中的循环,但建议sapply()
更好,这还不够具体。您的两个示例都在R中形成循环。与
的
相比,sapply()
在编译代码中执行的循环稍微多一些,但是如果循环体是计算时间的主要部分,那么sapply()就是
使用编译的循环代码在很大程度上是不相关的,两种解决方案的执行时间非常相似。对R中循环的厌恶通常是S-Plus时代的宿醉,或者是因为编写了糟糕的R代码。@GavinSimpson-感谢您的澄清。我同意在许多情况下,执行时间可能类似。我认为sapply()
的主要优势在于它促进了更好的编码风格。实际上,我认为,对编写for
循环的厌恶通常会导致人们编写复杂的*应用代码/函数,而for()
循环则会更自然、更容易理解、更省力。
sapply(ns, function(n) round(rnorm(1, mean = n, sd = 1)))
ns <- c(10, 20, 40, 80, 160)
ni <- numeric(length = length(ns)) ## pre-allocate storage
for (n in seq_along(ns)) {
ni[n] <- round(rnorm(1, mean = ns[n], sd = 1))
}
> ni
[1] 12 21 40 80 160
ns <- c(10, 20, 40, 80, 160)
ni <- numeric(length = length(ns)) # keeping this as per Victor's earlier post#
y=0 #adding starting counter#
for (i in ns) { # ns is already defined with its numeric sequence on line 1 of the
# code #
y=y+1 # counter used in the ni vector
ni[[y]] <- meanX(i) # preferable to create a custom function but not mandatory
}
ni # will produce only the 5 outputs of the rnorm function
# 11 21 41 81 161
## Custom function ##
meanX <-function(meanX) {round(rnorm(1, mean = meanX, sd = 1))
return(round(rnorm(1, mean = meanX, sd = 1)))
}
## end of Custom function ##