2016-04-06 89 views
4

几乎在您完成对R的介绍之后,您可能已经学习了for循环的语法,因此您会被告知避免R中的循环!何时在R中使用for循环

R是一个量化的语言,所以你是永远不会做这样的事情

x = 1:10 
y = 2:11 
z = rep(NA, 10) 
for i in 1:10{  
    z[i] = x[i] + y[i]  
} 

,而是做告诉

z = x + y 

您也告知使用的*层职能的家人迭代循环目的。

我的问题是,除了潜在的代码可读性情况之外,有没有好的时间用于R中的循环?

+2

假设您想要在每次运行中分配值并将该值用于后续运行,可以使用'for'循环。虽然'减少'具有类似的潜力,我认为''循环'更好。 – akrun

+1

请参阅Patrick Burns的R Inferno。只要预先分配对象,循环就可以。如果你想要超级速度,你最好使用一些专门的技术,比如使用'data.table'或者使用'Rcpp'。 –

+1

此类问题已被问及。 @germcd找到了你的链接。 http://chat.stackoverflow.com/transcript/message/29792007#29792007 –

回答

3

Advanced R提到了三种情况循环:就地修改,递归函数和while循环。既然你问了for环路,这里是什么是对前两种情况的书面:

修改到位

如果您需要修改现有的数据帧的一部分,它通常最好使用for循环。例如,以下代码通过将函数列表的名称与数据框中变量的名称进行匹配来执行逐变量变换。

trans <- list(
    disp = function(x) x * 0.0163871, 
    am = function(x) factor(x, levels = c("auto", "manual")) 
) 
for(var in names(trans)) { 
    mtcars[[var]] <- trans[[var]](mtcars[[var]]) 
} 

我们通常不会使用lapply()来直接替换这个循环,但它是可能的。

递推关系

很难转换for循环成一个功能时元件之间的关系是不是独立的,或者是递归定义。例如,指数平滑通过对当前和以前的数据点进行加权平均来工作。下面的exps()函数实现了for循环的指数平滑。

exps <- function(x, alpha) { 
    s <- numeric(length(x) + 1) 
    for (i in seq_along(s)) { 
    if (i == 1) { 
     s[i] <- x[i] 
    } else { 
     s[i] <- alpha * x[i - 1] + (1 - alpha) * s[i - 1] 
    } 
    } 
    s 
} 
x <- runif(6) 
exps(x, 0.5) 
#> [1] 0.6622163 0.6622163 0.4758159 0.2703593 0.1896377 0.5506731 0.7300305 

我们不能消除的循环,因为我们没有看到允许在位置i的输出依赖于输入和输出两个位置i的泛函 - 1

+0

预研仅仅是指当情况for循环为了提高可读性更好,这是不是他问 – adaien

1

创建图表的多页pdf。或者是每一次迭代都需要很长时间的事情,就像情节的生成一样。如果循环不是瓶颈,那么对我来说它几乎总是更具可读性,所以我这样做。

pdf("file.pdf", onefile=TRUE) 
for(var in unique(df$some_var)){ 
    p <- ggplot(df[df$some_var==var, ], aes(x=x, y=y)) + geom_line() 
    print(p) 
} 
dev.off() 
+0

这其实是我的问题的确切动机!我做了这件事,并对自己说:“呃,当我最后一次为R写一个for循环?” – NewNameStat