开发者

Dangerous for loop idiom?

taking an example from An Introduction to R

xc <- split(x, ind)
yc <- split(y, ind)
for (i in 1:length(yc)) {
    plot(xc[[i]], yc[[i]])
    abline(lsfit(xc[[i]], y开发者_如何学运维c[[i]]))
}

It seems that for(i in 1:length(yc)) { ... is an idiom for iterating over a list or vector in the case where you need a handle on the current index. This however breaks in the case of an empty list since 1:0 is not an empty vector. What is the idiom I should use for iterating over list/vector indices when you aren't guaranteed a non-empty list? I'm thinking if(length(yc)) for(i in 1:length(yc)) { ... but is there a nicer way?


You're looking for seq_along.

> seq_along(as.list(1:2))
[1] 1 2
> seq_along(list())
integer(0)


You can use seq_along:

for(i in seq_along(yc)) {...}

I'm pretty sure this bypasses the problem and should be a tiny bit faster.


This question is covered on page 75 of 'The R Inferno': http://www.burns-stat.com/pages/Tutor/R_inferno.pdf

It tells you a few other ways to get your loop wrong as well.


For anyone who happens to stumble upon this -- if you want an index vector based on possibly zero length, rather than another vector, you can safely use seq(1, length.out = L), where L can be any non-negative integer. That will give you integer(0) if L == 0, and 1:L otherwise.

Of course the other solutions given here are more concise if L == length(something), but I had a problem where that wasn't the case, so I thought I'd write it down for progeny.

Also seq(1, length.out = L) can be abbreviated as seq_len(L), which according to ?seq is faster.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜