我正在尝试初始化一个包含2列和40行的data.frame,我将继续添加行。这是我的代码 -
result.frame = as.data.frame(matrix(ncol=2, nrow=10))
names(result.frame) = c("ID", "Value")
for (i in 1:10) {
value = somefunction(i)
rbind(result.frame, c(i, value))
}
当我运行这个时,我只是得到一个包含NA的data.frame。另外,我在SO上读到,动态增长的结构是在R中编码最低效的方法之一。如果这是真的,那么完成这样的事情的正确方法是什么?
非常感谢!
答案 0 :(得分:6)
您没有将结果框分配给任何东西!下面的代码执行我认为您试图显示的内容。但是正如你所提到的那样,效率很低。
result.frame = as.data.frame(matrix(ncol=2, nrow=10))
names(result.frame) = c("ID", "Value")
for (i in 1:10) {
value = 2 * i
result.frame = rbind(result.frame, c(i, value))
}
而是将data.frame设置为您想要的完整大小并分配到其中:
result.frame = as.data.frame(matrix(ncol=2, nrow=20))
names(result.frame) = c("ID", "Value")
for (i in 11:20) {
value = 2 * i
result.frame[i,] = c(i, value)
}
breif timinigs:
> result.frame=data.frame()
> system.time(for(i in 1:10000){result.frame=rbind(result.frame, c(i,i*2))})
user system elapsed
9.844 0.000 9.874
> result.frame=as.data.frame(matrix(ncol=2, nrow=10000))
> system.time(for(i in 1:10000){result.frame[i,]=c(i,i*2)})
user system elapsed
7.041 0.056 7.120
>
除了时间效率之外,随着数据变得越来越大,也存在重要的内存问题。要执行rbind
操作,必须复制数据,这意味着在连续块中需要两倍的内存。分配给已创建的data.frame
没有此问题。
答案 1 :(得分:3)
这是怎么回事:NA来自matrix
,因为你没有用任何值进行初始化。 rbind
没有做任何事情,因为你已经放弃了返回值。
result.frame = data.frame( )
for( i in 1:10 ) {
value = somefunction( i )
result.frame = rbind( result.frame, c( i, value ) )
}
colnames( result.frame ) <- c( "ID", "Value" )
除非我们在这里谈论数百万次操作,否则不要担心效率。通常,计算比R需要在此处进行的这种小内存重新分配要强得多。
此外,您的效率也很重要,当您需要首先计算您需要的矩阵行数时,它会受到影响。