2012-12-28 43 views
5

Tôi có một Rscript đang đọc trong một dòng dữ liệu liên tục dưới dạng một tệp phẳng. Một tập lệnh khác chọn tệp phẳng này, thực hiện phân tích cú pháp và xử lý, sau đó lưu kết quả dưới dạng tệp data.frame ở định dạng RDS. Sau đó nó ngủ và lặp lại quá trình.Nối dữ liệu mới vào một khung dữ liệu hiện có (RDS) trong R

saveRDS(tmp.df, file="H:/Documents/tweet.df.rds") #saving the data.frame 

Trong lần lặp thứ hai ... nth, tôi có mã chỉ xử lý dòng mới được thêm vào tệp phẳng kể từ lần lặp trước đó. Tuy nhiên, để nối thêm các đường delta vào khung dữ liệu cố định, tôi phải đọc nó trong, chắp thêm và sau đó lưu nó lại, ghi đè lên bản gốc.

df2 <- readRDS("H:/Documents/tweet.df.rds") #read in permanent      
tmp.df2 <- rbind(df2, tmp.df) #append new to existing 
saveRDS(tmp.df2, file="H:/Documents/tweet.df.rds") #save it 
rm(df2) #housecleaning 
rm(tmp.df2) #housecleaning 

Cách tiếp cận này là mạo hiểm vì bất cứ khi nào RDS mở cửa cho việc đọc/ghi, một quá trình muốn chạm vào tập tin đó có phải chờ đợi. Khi tệp cơ sở trở nên lớn hơn, nguy cơ tăng lên.

Có gì giống như một appendRDS (Tôi biết nghĩa là không) có thể đạt được những gì tôi muốn lặp lại cập nhật của một khung dữ liệu duy nhất- được lưu vào một tệp- sử dụng thay thế thay vì hoàn thành?

+0

Vâng, tôi nghĩ bạn đang làm điều xấu ngay từ đầu. Bạn đang ghi đè lên dữ liệu trước đó của bạn, do đó có hiệu quả xóa các phiên bản trước đó. Điều đó nói rằng, tại sao không chỉ lưu dữ liệu của bạn dưới dạng văn bản (CSV, ví dụ) với 'write.table', cho phép phụ thêm vào tài liệu hiện có? –

+0

Tôi thực sự ghi đè lên dữ liệu trước đó với một bản sao của dữ liệu trước đó rbind'd cho các hồ sơ mới nhất. Hy vọng rằng khối thứ hai của tôi cho thấy rằng quá trình đọc trong cũ, nối mới, ghi đè cũ với cũ + mới. Bây giờ tôi thấy tùy chọn chắp thêm write.table. Tôi đã tránh xa một định dạng không phải bản địa bởi vì tôi nghĩ rằng nó sẽ làm tăng chi phí xử lý. Nhưng tôi có thể ổn với việc giao dịch một chút không hiệu quả trong bước đó để ổn định hơn. –

+0

Tôi tự hỏi nếu một số phép thuật với serialize có thể được sử dụng để tạo ra một chức năng phụ thêm. –

Trả lời

2

Tôi nghĩ bạn có thể bảo vệ quy trình của mình bằng cách sử dụng các kết nối, mở và đóng nó trước khi quá trình tiếp theo tiếp quản.

con <- file("tmp.rds") 
open(con) 
df <- readRDS(con) 
df.new <- rbind(df,df) 
saveRDS(df.new, con) 
close(con) 

Cập nhật:

Bạn có thể kiểm tra nếu một kết nối đến tập tin mở cửa và nói với nó để chờ một chút nếu bạn đang gặp vấn đề với đồng thời.

while(is.Open(con)) { # untested but something of this nature should work 
sys.Sleep(2) 
} 
+0

Cảm ơn bạn. Có vẻ như nó sẽ hoạt động trong cùng một tập lệnh. Điều đó có giúp bảo vệ nó nếu một tập lệnh khác (tức là, một quy trình khác) đang truy cập cùng một RDS đó cùng một lúc không? Tôi sợ kinh nghiệm duy nhất của tôi với sự đồng thời là với cơ sở dữ liệu, không phải với các tệp. –

+0

@ Brandon-Bertselsen Đã hoạt động! '# pass1 con <- file ("H: /Documents/tweet.df.rds") \t while (ISOpen (con)) { \t \t Sys.sleep (2) \t} \t mở (con , "wb") \t saveRDS (tmp.df, con) \t đóng (con, type = "rw") #Pass N con <- tệp ("H: /Documents/tweet.df.rds") \t while (ISOpen (con)) { \t \t Sys.sleep (2) \t} \t mở (con, "rb") \t df2 <- readRDS (con) \t gần (con, type = "rw") \t tmp.df2 <- rbind (df2, tmp.df) \t \t con <- file ("H: /Documents/tweet.df.rds") \t while (ISOpen (con)) { \t \t Sys.sleep (2) \t} \t mở (con, "wb") \t saveRDS (tmp.df2, con) \t close (con, type = "rw") ' Có thể một số quá mức cần thiết khi mở/đóng, nhưng tôi ổn với điều đó. –

1

Có điều gì sai khi sử dụng hàng loạt tệp RDS được đánh số trong thư mục thay vì tệp RDS duy nhất không? Tôi không nghĩ là có thể gắn thêm vào một khung dữ liệu một tệp RDS mà không cần viết lại toàn bộ tệp, vì khung dữ liệu chỉ đơn giản là danh sách các cột, vì vậy có lẽ chúng được nối tiếp một cột tại một thời điểm, vì vậy chỉ có cột cuối cùng kết thúc ở gần cuối tập tin.

Nếu bạn muốn gắn bó với một tệp nhưng giảm thiểu nguy cơ đọc dữ liệu không phù hợp từ tệp RDS, bạn có thể đọc nó, thực hiện thao tác chắp thêm rồi ghi nó ra tệp tạm thời và đổi tên temp tập tin vào tên gốc khi nó được hoàn thành. Sau đó, ít nhất là khoảng thời gian rủi ro của bạn không phụ thuộc vào kích thước của tệp. Tôi không quen thuộc với loại nguyên tử được đảm bảo bởi hệ thống tập tin khác nhau khi đổi tên một tập tin thành một tên hiện có, nhưng nó có lẽ tốt hơn so với thời gian được thực hiện bởi saveRDS.

+0

Ý tưởng thú vị. Nó sẽ mất một chút smithing để có được tất cả các tập tin RDS đọc trong; và sau đó tiếp cận hệ điều hành để thực hiện việc thả/đổi tên. Thông minh, nhưng vượt quá sự kiên nhẫn của tôi;). –

+0

Bạn có thể viết một hàm hoạt động như một thay thế thả cho 'saveRDS' ghi vào tệp tạm thời và đổi tên. –

Các vấn đề liên quan