2012-11-18 32 views
18

Tôi đang cố gắng điền một khung dữ liệu từ trong vòng lặp for trong R. Tên của các cột được tạo động trong vòng lặp và giá trị của một số biến vòng lặp được sử dụng làm giá trị trong khi điền vào khung dữ liệu. Ví dụ, tên của cột hiện tại có thể là một số tên biến như một chuỗi trong vòng lặp và cột có thể lấy giá trị của trình lặp hiện tại làm giá trị của nó trong khung dữ liệu.Điền vào một khung dữ liệu trong R theo vòng lặp

tôi đã cố gắng để tạo ra một khung dữ liệu rỗng bên ngoài vòng lặp, như thế này

d = data.frame() 

Nhưng tôi không thể thực sự làm bất cứ điều gì với nó, thời điểm tôi cố gắng để cư nó, tôi chạy vào một lỗi

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

Điều gì có thể là cách hay để đạt được những gì tôi đang muốn làm. Xin vui lòng cho tôi biết nếu tôi không rõ ràng.

+1

cư a 'list' thay vì một 'data.frame' và biến nó thành một' data.frame' sau vòng lặp. – Roland

+2

Cảm ơn Roland, tôi là một n00b, bạn có thể vui lòng giải thích thêm? Làm thế nào để khai báo danh sách, và làm thế nào để chuyển đổi nó? –

Trả lời

28

Bạn có thể làm điều đó như thế này:

iterations = 10 
variables = 2 

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

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

} 

output 

và sau đó biến nó thành một data.frame

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

điều này không:

  1. tạo ra một ma trận với các hàng và cột theo với mức tăng trưởng dự kiến ​​
  2. chèn 2 đã chạy số dom vào ma trận
  3. chuyển đổi số này thành một khung dữ liệu sau vòng lặp kết thúc.
35

Thường thích hợp hơn là tránh các vòng lặp và sử dụng các chức năng được vector hóa. Nếu không thể, có hai cách tiếp cận:

  1. Preallocate data.frame. Điều này không được khuyến nghị vì lập chỉ mục chậm cho data.frames.
  2. Sử dụng cấu trúc dữ liệu khác trong vòng lặp và chuyển thành một số data.frame sau đó. Một list là rất hữu ích ở đây.

Ví dụ để minh họa cho cách tiếp cận chung:

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 

Trong ví dụ này nó không phải là cần thiết để sử dụng một list, bạn có thể preallocate một matrix. Tuy nhiên, nếu bạn không biết có bao nhiêu lần lặp mà vòng lặp của bạn sẽ cần, bạn nên sử dụng list.

Cuối cùng đây là một thay thế vectorized với ví dụ vòng lặp:

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

Như bạn thấy nó đơn giản hơn và cũng hiệu quả hơn.

+4

Bạn có thể đơn giản hóa phiên bản vectơ của bạn thậm chí nhiều hơn như: 'bên ngoài (1: 5,1: 5,"^")' – thelatemail

0

Tôi đã có một trường hợp trong đó tôi đã cần phải sử dụng một khung dữ liệu trong một chức năng vòng lặp for. Trong trường hợp này, đó là "hiệu quả", tuy nhiên, hãy ghi nhớ rằng cơ sở dữ liệu là nhỏ và lặp lại trong vòng lặp rất đơn giản.Nhưng có lẽ mã có thể hữu ích cho một số người có điều kiện tương tự.

Các vòng lặp for Mục đích là để sử dụng raster chiết xuất chức năng cùng năm địa điểm (tức là từ 5 Tokio, New York, Sáu Paulo, thành phố Seul & Mexico) và mỗi địa điểm có lưới raster tương ứng của họ. Tôi đã có một cơ sở dữ liệu không gian với hơn 1000 quan sát được phân bổ trong 5 địa điểm khác nhau và tôi cần trích xuất thông tin từ 10 lưới raster khác nhau (hai lưới trên mỗi vị trí). Ngoài ra, đối với phân tích tiếp theo, tôi không chỉ cần các giá trị raster mà còn là ID duy nhất cho mỗi quan sát.

Sau khi chuẩn bị các dữ liệu không gian, trong đó bao gồm các nhiệm vụ sau:

  1. điểm nhập shapefile với readOGR chức năng (gói rgdap)
  2. Nhập các tập tin raster với raster chức năng (gói raster)
  3. Ngăn xếp lưới từ cùng một vị trí vào một tệp, với hàm ngăn xếp (gói raster)

Ở đây vòng lặp for mã với việc sử dụng một khung dữ liệu:

1. Add xếp chồng lên nhau rasters mỗi vị trí vào một danh sách

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

2. Tạo một trống dataframe, đây sẽ là tệp xuất

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

3. Thiết lập cho chức năng loop

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) 
} 
Các vấn đề liên quan