Dir*_*tel 92
您可以通过追加或使用逐行增长它们rbind().
这并不意味着你应该这样做.动态增长的结构是在R中编码最低效的方法之一.
如果可以,请预先分配整个data.frame:
N <- 1e4 # total number of rows to preallocate--possibly an overestimate
DF <- data.frame(num=rep(NA, N), txt=rep("", N), # as many cols as you need
stringsAsFactors=FALSE) # you don't know levels yet
Run Code Online (Sandbox Code Playgroud)
然后在您的操作期间一次插入行
DF[i, ] <- list(1.4, "foo")
Run Code Online (Sandbox Code Playgroud)
这应该适用于任意data.frame并且效率更高.如果你超过N,你总是可以在最后收缩空行.
mbq*_*mbq 47
可以添加行到NULL:
df<-NULL;
while(...){
#Some code that generates new row
rbind(df,row)->df
}
Run Code Online (Sandbox Code Playgroud)
例如
df<-NULL
for(e in 1:10) rbind(df,data.frame(x=e,square=e^2,even=factor(e%%2==0)))->df
print(df)
Run Code Online (Sandbox Code Playgroud)
这是一个如何do.call(rbind,)在Map()[类似lapply()] 的输出上使用的愚蠢的例子
> DF <- do.call(rbind,Map(function(x) data.frame(a=x,b=x+1),x=1:3))
> DF
x y
1 1 2
2 2 3
3 3 4
> class(DF)
[1] "data.frame"
Run Code Online (Sandbox Code Playgroud)
我经常使用这个结构.
我之所以如此喜欢Rcpp,是因为我并不总是了解R Core的想法,而且通常使用Rcpp,我不需要.
哲学上说,你在与问候的功能模式,它试图以确保每一个价值罪的状态出现独立每隔价值; 更改一个值不应该导致另一个值的可见更改,使用指针在C中共享表示的方式.
当功能性编程发出信号表示小型船只移开时,问题就出现了,小型工艺人员回答"我是一座灯塔".在此期间对要处理的大对象进行一系列小的更改会使您成为灯塔区域的正方形.
在C++ STL中,push_back()是一种生活方式.它不会尝试是功能性的,但它确实尽力满足常见的编程风格有效.
在幕后有些聪明,你有时可以在每个世界中安排一只脚.基于快照的文件系统就是一个很好的例子(它是从诸如联合安装之类的概念发展而来的,它也是双方的一部分).
如果R Core想要这样做,底层矢量存储可以像union mount一样运行.对向量存储的一个引用可能对下标有效1:N,而对同一存储的另一个引用对下标有效1:(N+1).可能有任何保留存储尚未被有效引用,但方便快捷push_back().在超出任何现有引用认为有效的范围之外时,不违反功能概念.
最终以递增方式追加行,您的预留存储空间不足.你需要创建所有东西的新副本,存储乘以一些增量.我使用的STL实现在扩展分配时倾向于将存储乘以2.我以为我在R Internals中读到有一个内存结构,其中存储增加了20%.无论哪种方式,增长操作都以相对于附加元素总数的对数频率发生.在摊销的基础上,这通常是可以接受的.
作为幕后花样,我看到了更糟.每次push_back()在数据帧上添加新行时,都需要复制顶级索引结构.新行可以附加到共享表示,而不会影响任何旧的功能值.我甚至认为它不会使垃圾收集器复杂化; 因为我不建议push_front()所有引用都是对分配的向量存储的前面的前缀引用.