2012-11-18 152 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) 
}