9.2 循环变化
9.2.1 修改已有对象
<- 1:100
res for(i in seq_along(res)){
<- res[i] * i
res[i]
}str(res)
#> int [1:100] 1 4 9 16 25 36 49 64 81 100 ...
9.2.2 循环模式
共有三种遍历向量的方法,之前展示的都是遍历数字索引for (i in seq_along(xs))
,并使用提取值x[[i]]
。除此之外,还有两种方式:
- 循环遍历元素
for(i in xs)
,例如我们需要保存文件时,可以利用这种循环模式
- 遍历名称
for (nm in names(xs))
,我们可以使用x[[nm]]
该名称访问.当我们要在文件名中使用名称时会比较方便.
<- vector("list", length(x))
results names(results) <- names(x)
数字索引的循环模式最常用,因为可以根据位置提取名称和值.
for (i in seq_along(x)) {
<- names(x)[[i]]
name <- x[[i]]
value }
9.2.3 未知长度输出
有时候我们的循环我们不确定输出的长度是多少.这样会逐步增加向量的长度,如下所示:
<- c(0, 1, 2)
means
<- double()
output for (i in seq_along(means)) {
<- sample(100, 1)
n <- c(output, rnorm(n, means[[i]]))
output
}str(output)
#> num [1:69] 0.255 -0.553 1.405 -0.795 -1.567 ...
但是这种方式浪费时间,当数据量大时候效率会很低下。因为时间复杂度为(\(O(n^2)\)),解决方案是将结果保存在列表中,然后在完成循环后合并为单个向量:
<- vector("list", length(means))
out for (i in seq_along(means)) {
<- sample(100, 1)
n <- rnorm(n, means[[i]])
out[[i]]
}str(out)
#> List of 3
#> $ : num [1:89] -1.399 0.259 -0.442 0.569 2.127 ...
#> $ : num [1:81] 2.36 0.929 0.728 -1.447 1.065 ...
#> $ : num [1:35] 0.0381 2.946 2.549 1.4225 0.7717 ...
str(unlist(out)) #unlist将列表向量化
#> num [1:205] -1.399 0.259 -0.442 0.569 2.127 ...