[英]Using for loop instead of matrix index in [r]
I have been meaning to rewrite the following code with for loop in R:我一直想在R用for循环改写如下代码:
x <- sample(1:100, 10)
x[x %% 2 == 0]
#[1] 6 26 72 62 32 86 100
which extracts those elements in vector x that are even number only.它提取向量 x 中仅为偶数的那些元素。 I have come up with the following result in the end, but I believe there are more simple ways of coding this.
我最终得出了以下结果,但我相信还有更简单的编码方法。
x <- sample(1:100, 10)
output <- integer(0)
for(i in seq_along(x)) {
if(x[i] %% 2 == 0) {
output[i] <- x[i]
output <- output[!is.na(output)]
}
}
output
#[1] 6 26 72 62 32 86 100
I would be grateful if you could help me with this.如果你能帮我解决这个问题,我将不胜感激。
You can skip the NA
removes when adding the new hit to the end of output
using length
.使用
length
将新命中添加到output
的末尾时,您可以跳过NA
删除。
output <- integer(0)
for(i in seq_along(x)) {
if(x[i] %% 2 == 0) {
output[length(output) + 1] <- x[i]
}
}
output
Where length(output)
gives you the current length of output. By adding 1 you place the new element at the end of output
.其中
length(output)
为您提供当前长度 output。通过添加 1,您将新元素放在output
的末尾。
Or as @Roland (thanks!) commented using c
或者正如@Roland(谢谢!)使用
c
评论的那样
output <- integer(0)
for(i in seq_along(x)) {
if(x[i] %% 2 == 0) {
output <- c(output, x[i])
}
}
output
c
combines output
and x[i]
to a new vector. c
将output
和x[i]
组合成一个新向量。
Or preallocate output
with x
and mark the non hits with NA
或者用
x
预分配output
并用NA
标记未命中
output <- x
for(i in seq_along(x)) {
if(x[i] %% 2 != 0) {
output[i] <- NA
}
}
output <- output[!is.na(output)]
output
Benchmarks:基准:
fun <- alist(Vectorized = x[x %% 2 == 0]
, Question = {output <- integer(0)
for(i in seq_along(x)) {
if(x[i] %% 2 == 0) {output[i] <- x[i]; output <- output[!is.na(output)]}
}
output}
, NaOutside = {output <- integer(0)
for(i in seq_along(x)) {
if(x[i] %% 2 == 0) {output[i] <- x[i]}
}
output <- output[!is.na(output)]
output}
, Append = {output <- integer(0)
for(i in seq_along(x)) {
if(x[i] %% 2 == 0) {output[length(output) + 1] <- x[i]}
}
output}
, Append2 = {output <- integer(0); j <- 1
for(i in seq_along(x)) {
if(x[i] %% 2 == 0) {output[j] <- x[i]; j <- j + 1}
}
, C = {output <- integer(0)
for(i in seq_along(x)) {
if(x[i] %% 2 == 0) {
output <- c(output, x[i])
}
}
output}
, Preallocate = {output <- x
for(i in seq_along(x)) {
if(x[i] %% 2 != 0) {
output[i] <- NA
}
}
output <- output[!is.na(output)]
output}
)
library(microbenchmark)
set.seed(42)
x <- sample(1:100, 10)
microbenchmark(list = fun, control=list(order="block"))
#Unit: nanoseconds
# expr min lq mean median uq max neval
# Vectorized 644 655 781.54 666.5 721 8559 100
# Question 4377648 4419010 4682029.95 4492628.5 4579952 7512162 100
# NaOutside 3443488 3558401 3751542.62 3597273.0 3723662 5146015 100
# Append 3932586 4070234 4287628.11 4129849.0 4209361 6036142 100
# Append2 3966245 4094766 4360989.39 4147847.5 4312868 5899000 100
# C 3464081 3566902 3806531.77 3618758.5 3743058 6528224 100
# Preallocate 3162424 3263220 3435591.92 3290938.0 3374547 4823017 100
set.seed(42)
x <- sample(1:1e5, 1e4)
microbenchmark(list = fun, control=list(order="block"))
#Unit: microseconds
# expr min lq mean median uq max neval
# Vectorized 226.224 276.271 277.0027 278.993 284.4515 345.527 100
# Question 125550.120 126392.848 129287.7202 126812.309 128426.3655 157958.571 100
# NaOutside 6911.053 7020.831 7497.4403 7109.891 8158.7580 8779.448 100
# Append 7843.988 7982.987 8582.6769 8129.988 9287.5760 10775.894 100
# Append2 7647.340 7783.334 8347.7824 7954.683 9007.4500 10325.973 100
# C 27976.747 29776.632 29997.5407 30024.121 30250.9590 51630.868 100
# Preallocate 6119.198 6232.228 6679.9407 6367.618 7290.1015 8331.277 100
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.