2013-07-19 19 views
6

Bir PostgreSQL veritabanından veri çekmeye çalışıyorum ve zaman damgası alanı sonuçları tutarsız. POSIXct sonuçlarını doğru kullanıp kullanmadığımı bilmiyorum. Aksi halde, RPostgreSQL paketinde bir hata buldum.RPostgreSQL kullanarak verileri çekerken R'de zaman damgası sütunlarını işlemenin belirli bir yolu var mı?

bir alanda (PostgreSQL bu çalıştırın) ile postgres veritabanı bir tablo bulunduğunu varsayalım:

CREATE DATABASE mydb; 
CREATE TABLE test_table 
( 
    "DateTime" timestamp without time zone NOT NULL, 
    CONSTRAINT "pk_test_table" PRIMARY KEY ("DateTime") 
) 
WITH (
    OIDS=FALSE 
); 
ALTER TABLE test_table 
    OWNER TO postgres; 

Ve en birkaç yüz kayıtları vardır diyelim Burada konuyu çoğaltmak için bir yoldur. Ben değerlerini almaya çalışırsanız

library(RPostgreSQL) 

# Let's feed the table with some sequence of date/time values 
date_values <- as.chron(seq(10000, 10500, 1/24)) 

format.chron <- function(z) { 
    sprintf("%04.0f-%02.0f-%02.0f %02.0f:%02.0f:00", 
      as.numeric(as.character(years(z))), 
      months(z), 
      as.numeric(as.character(days(z))), 
      as.numeric(as.character(hours(z))), 
      as.numeric(as.character(minutes(z)))) 
} 

.generateInsertQuery <- function(date_values, field_name, table_name) { 
    insert_val <- paste(paste0("(", sQuote(format(date_values)), ")"), collapse=',') 
    qry   <- paste("INSERT INTO", dQuote(table_name), paste0("(", dQuote(field_name), ")"), "VALUES", insert_val) 
    qry 
} 

drv <- dbDriver('PostgreSQL') 
con <- dbConnect(drv, user='postgres', dbname='mydb') 
qry <- .generateInsertQuery(date_values, "DateTime", "test_table") 
dbSendQuery(con, qry) 

, zaman bileşeni ortaya çıkan verilerin

res <- dbGetQuery(con, "SELECT * FROM test_table") 
res[1:20,1] 

sonucun sınıf dışına soyulmuş alır: R. İşte kod içinde onları dolduracaktır sonuç, her seferinde bir kayıt, bir saat ile değerleri getirilen, ancak, POSIXct

class(res[,1]) 

olup:

012.351: 00-00 eşit dakika zaman bileşeni gevşek
rs <- dbSendQuery(con, "SELECT \"DateTime\" FROM test_table") 
res_list <- list() 
for(i in 1:100) res_list[i] <- fetch(rs,1) 
res_list 

Bir geçici çözüm olarak, sonuç 1 kayıtlarını bir seferde getiriyorum, bir sabitleme ve bir data.frame içine topluyorum. Ancak bu, özellikle büyük veri kümeleri için çok zaman alıcıdır. Bunun neden olduğu ve bu konuyla nasıl baş edileceğine dair herhangi bir fikir var mı?

Şimdiden teşekkürler!

+0

Yukarıda belirtildiği gibi, 'CREATE TABLE' ifadesinde ' timezon'lu zaman damgası kullanılarak benim için numara oldu.Sorunun gerçekten bir parçası olmasa da, deneyimlerime göre dbWriteTable'ın SQL tablo isimlerini yazarken belirttiği ** büyük harflerden hoşlanmadığını buldum. – bibzzzz

cevap

3

İlk kapalı, RPostgreSQL projesinin bir posta listesi vardır; Orada mesaj atmanızı öneriyorum.

PostgreSQL'in iki adet tarih türü vardır: saat dilimi olan ve olmayan. Hatırladığım gibi, R sadece ikincisini arar. Bunun için bazı erken regresyon testleri yaptım (paket kaynağına bakın) ama geç proje ile ilgili olmamıştı. Ancak, POSIXct'in PostgreSQL datetime tipine çok iyi bir şekilde geri döndüğünü hatırlıyorum. olursa olsun ne olacağını posixct saat dilimi daima tz +00 ile tip timestamp with timezone veritabanı alanını yaratacak herhangi posixct alanıyla

+0

Öneri @Dirk öneri için. Benim durumumda, saat dilimi olmayan zaman damgası kullanıyorum ve hala yukarıda açıklanan sorunu buluyorum. Posta listesini deneyeceğim. – JAponte

+1

Saat dilimi ile zaman damgası deneyin ve işe yarayıp yaramadığını görün. UTC'yi her zaman bir saat dilimi olarak kullanabilirsiniz. –

+0

İpucu @Dirk için tekrar teşekkürler. 2000 ile 2010 yılları arasında POSIX değerlerinin uzun bir vektörünü hiçbir sorun olmadan itip çekebiliyordum. Bu nedenle, saat dilimi olmayan zaman damgası desteklenmeyen türden gibi görünüyor. Bu, daha da iyisi, önceki yaklaşımım veri kullanıcıları arasında karışıklık yaratabilecek zaman dilimi açısından belirsizdi. – JAponte

4

RPostgreSQL en dbWriteTable. Bunun yerine timestamp without timezone oluşturmak daha doğru olacaktır.

dbReadTable ve dbWriteTable için en iyi çözüm Sys.setenv(TZ = "UTC") kullanmaktır. Benim düşünceme göre, çok derin bir bağımlılık çünkü R oturumundaki diğer birçok işlem uygun saat dilimi ayarını gerektirebilir. Çok daha spesifik ve bağımlı derin için

kendi tanımlamaktır dbReadTable ve posixct tiplerinin uygun preprocess/postprocess ile DBI versiyonunu sarar dbWriteTable. Ancak DBI uyumlu kod/paket geliştiriyorsanız (sadece postgres ile ilgili değil) bir seçenek değildir.

Daha kolay katkı için RPostgreSQL'in github'a taşınması harika olurdu.

+2

GitHub'da yaşayan yeni RPostgres projesine bakın ... – hadley

İlgili konular