在R中,如何快速循环数据帧的行?

在R中,如何快速循环数据帧的行?,r,performance,dataframe,iteration,rows,R,Performance,Dataframe,Iteration,Rows,假设您有一个包含许多行和许多列的数据框 这些列有名称。您希望按编号访问行,按名称访问列 例如,循环行的一种(可能较慢)方法是 for (i in 1:nrow(df)) { print(df[i, "column1"]) # do more things with the data frame... } 另一种方法是为单独的列(如column1\u list=df[[“column1”])创建“列表”,并在一个循环中访问列表。这种方法可能很快,但如果您想访问多个列,也不方便 是否有一种

假设您有一个包含许多行和许多列的数据框

这些列有名称。您希望按编号访问行,按名称访问列

例如,循环行的一种(可能较慢)方法是

for (i in 1:nrow(df)) {
  print(df[i, "column1"])
  # do more things with the data frame...
}
另一种方法是为单独的列(如
column1\u list=df[[“column1”]
)创建“列表”,并在一个循环中访问列表。这种方法可能很快,但如果您想访问多个列,也不方便

是否有一种快速循环数据帧行的方法?是否有其他数据结构更适合快速循环?

最快的方法是不循环(即矢量化操作)。您需要循环的唯一实例之一是存在依赖项时(即一个迭代依赖于另一个迭代)。否则,请尝试在循环外进行尽可能多的矢量化计算


如果确实需要循环,那么使用
for
循环基本上与其他任何循环一样快(
lappy
可以快一点,但是).

我想我需要给出一个完整的答案,因为我发现评论很难跟踪,而且我已经失去了一条关于这个的评论…有一个例子说明了for函数之间的差异,并且比其他例子更好地应用了族函数。当一个函数的速度非常慢时,这就是所有速度的所在当函数被消耗时,你不会发现循环变量之间的差异。但是当你使函数变得微不足道时,你可以看到循环对事物的影响有多大

我还想补充一点,在其他示例中未探讨的apply系列的一些成员具有有趣的性能属性

n <- 1e6
system.time(for(i in 1:n) sinI[i] <- sin(i))
  user  system elapsed 
 5.721   0.028   5.712 

lapply runs much faster for the same result
system.time(sinI <- lapply(1:n,sin))
   user  system elapsed 
  1.353   0.012   1.361 

n利用data.frames本质上是列向量的列表这一事实,可以使用do.call在data.frame的每列上应用列数的算术函数(类似于其他语言中列表的“压缩”)


这与df[,“column1”]有何不同?另请参见?应用时边距=1。这个示例不是我真正想做的。我想在数据框中写入一些值作为javascript文件中的数据。+1获取“应用”中有关“边距”的信息。在特定情况下,我需要在行上循环以在列中移动值。有人提醒我,在R中实现这一点的更好方法是:也许没有办法避免我想做的事情的循环——请参阅我对格雷格上述评论的回复。“以同样的速度”?你读了所有的答案吗?在我的答案中,我展示了使用vapply比for循环快3倍(例如),就算法效率而言,它们在速度上非常相似:矢量化版本确实比for循环版本更有效,感谢@Shane+1对nullglob的引用。他的帖子引用了这篇文章Uwe Ligges和John Fox在“R新闻”中写道:“我如何避免这种循环或使其更快?”“,2008年5月。感谢您撰写有关应用函数的文章。但这不是循环。回答得很好,OP明确地问了‘如何在行上循环’。这是迄今为止最有效的方法,并且根本不需要
for
。我有一个
for
循环,现在采用了这种方法,速度提高了40倍左右!
mat <- matrix(1:n,ncol =1),1,sin)
system.time(sinI <- apply(mat,1,sin))
   user  system elapsed 
  8.478   0.116   8.531 
system.time(sinI <- tapply(1:n, 1:n, sin))
   user  system elapsed 
 12.908   0.266  13.589 
do.call(paste, data.frame(x=c(1,2), z=c("a","b"), z=c(5,6)))