2012-11-18 59 views
18

我试图从R中的for循环中填充数据框。列的名称是在循环内动态生成的,并且使用了一些循环变量的值作为填充数据框时的值。例如,当前列的名称可以是循环中字符串的某个变量名称,并且该列可以将当前迭代器的值作为数据框中的值。在循环中填充R中的数据帧

我试图创建循环外空的数据帧,这样

d = data.frame() 

但我真的不能对它做任何事,那一刻我尝试填充它,我碰到一个错误

d[1] = c(1,2) 
Error in `[<-.data.frame`(`*tmp*`, 1, value = c(1, 2)) : 
    replacement has 2 rows, data has 0 

什么可能是一种很好的方法来实现我期待的目标。如果我不清楚,请告诉我。

+1

填充'list'代替'data.frame',使之成为循环后'data.frame'。 – Roland

+2

感谢罗兰,我是一个n00b,你能否详细说明一下?如何声明列表以及如何转换它? –

回答

28

你可以做这样的:

iterations = 10 
variables = 2 

output <- matrix(ncol=variables, nrow=iterations) 

for(i in 1:iterations){ 
    output[i,] <- runif(2) 

} 

output 

,然后把它变成一个data.frame

output <- data.frame(output) 
class(output) 

这是什么一样:

  1. 创建根据行和列的矩阵到预期增长
  2. insert 2 ran dom数字转换成矩阵
  3. 在之后将此转换为数据帧循环已完成。
35

通常最好避免循环并使用向量化函数。如果这是不可能的,有两种方法:

  1. 预先分配您的data.frame。建议不要这样做,因为data.frames的索引速度很慢。
  2. 在循环中使用另一个数据结构,然后转换为data.frame。 A list在这里非常有用。

的例子来说明的一般方法:

mylist <- list() #create an empty list 

for (i in 1:5) { 
    vec <- numeric(5) #preallocate a numeric vector 
    for (j in 1:5) { #fill the vector 
    vec[j] <- i^j 
    } 
    mylist[[i]] <- veC#put all vectors in the list 
} 
df <- do.call("rbind",mylist) #combine all vectors into a matrix 

在这个例子中,没有必要使用list,你可以预先分配一个matrix。但是,如果您不知道循环需要多少次迭代,则应使用list

最后这里是一个矢量替代例如循环:

outer(1:5,1:5,function(i,j) i^j) 

正如你看到它更简单,也更有效率。

+4

您可以更简化矢量化版本,例如:'outer(1:5,1:5,“^”)' – thelatemail

0

我有一个情况,我需要在for循环函数中使用数据框。 在这种情况下,它是“高效”的,但请记住,数据库很小,并且循环中的迭代非常简单。但是,也许代码可能对某些具有类似条件的代码有用。

for循环目的是使用光栅提取功能从五个位置(即5东京,纽约,圣保罗秀,瑟&墨西哥城),每个单元有各自的栅格网格。我有一个空间点数据库,在5个不同的位置分配了1000多个观测值,我需要从10个不同的栅格网格(每个位置有两个网格)提取信息。此外,对于后续分析,我不仅需要栅格值,还需要每个观测值的唯一ID。

制备的空间数据,其中包括以下任务之后:

  1. 导入点shape文件与readOGR功能(rgdap封装)
  2. 导入光栅文件与光栅功能(光栅包)
  3. 将来自同一位置的栅格堆叠成一个文件,具有功能堆栈(栅格封装)

这里与使用一个数据帧的环代码:每个位置

1.添加堆叠栅格到一个列表

raslist <- list(LOC1,LOC2,LOC3,LOC4,LOC5) 

2.创建一个空数据帧,这将是输出文件

TB <- data.frame(VAR1=double(),VAR2=double(),ID=character()) 

3.设置循环功能

L1 <- seq(1,5,1) # the location ID is a numeric variable with values from 1 to 5 

for (i in 1:length(L1)) { 
    dat=subset(points,LOCATION==i) # select corresponding points for location [i] 
    t=data.frame(extract(raslist[[i]],dat),dat$ID) # run extract function with points & raster stack for location [i] 
    names(t)=c("VAR1","VAR2","ID") 
    TB=rbind(TB,t) 
}