2012-09-13 29 views
-1

說我有一個包含幾個條目像這樣的文件:R:從有序二元組創建全長時間序列有時間戳

02/10/11 10:26:35 AM UTC, 0 
02/10/11 10:26:38 AM UTC, 1 
02/10/11 10:26:42 AM UTC, 0 

有沒有什麼簡單的方法,在R,把這個信息轉換爲全長二進制時間序列(假設採樣間隔爲一秒),用零和一個值來表示?

在這個例子中系列將是:

編輯:由於德克和Josh了獨特的解決方案,我想看看他們在處理時間方面如何比較:

library(xts) 
library(data.table) 
library(rbenchmark) 

doseq <- function(N,Nby){ 
    base.t <<- Sys.time() 
    t.seq <<- base.t + seq.int(from=0, to=N, by=Nby) 
    n.t <<- length(t.seq) 
    val.seq <<- (1:n.t - 1) %% 2 
} 

josh <- function(N,Nby=10){ 
    doseq(N,Nby) 
    dt1 <- data.table(time = t.seq, val=val.seq, key="time") 
    dt2 <- data.table(time = with(dt1, seq(min(time), max(time), by=1)), key = "time") 
    dtf <- dt1[dt2, rolltolast = TRUE] 
    return(dtf) 
} 

dirk <- function(N,Nby=10){ 
    doseq(N,Nby) 
    xt1 <- xts(val.seq, t.seq) 
    secs <- seq(start(xt1), end(xt1), by="1 sec") 
    xtf <- zoo::na.locf(merge(xt1, xts(, secs))) 
    return(xtf) 
} 

bm <- benchmark(josh(1e2,10), josh(1e3,10), josh(1e4,10), josh(1e5,10), josh(1e6,10), 
    dirk(1e2,10), dirk(1e3,10), dirk(1e4,10), dirk(1e5,10), dirk(1e6,10), 
    columns=c("test", "replications","elapsed", "relative"), 
    replications=10) 

print(bm) 

捐贈:

   test replications elapsed relative 
6 dirk(100, 10)   10 0.024 1.000 
7 dirk(1000, 10)   10 0.026 1.083 
8 dirk(10000, 10)   10 0.044 1.833 
9 dirk(1e+05, 10)   10 0.321 13.375 
10 dirk(1e+06, 10)   10 3.342 139.250 
1 josh(100, 10)   10 0.034 1.417 
2 josh(1000, 10)   10 0.036 1.500 
3 josh(10000, 10)   10 0.070 2.917 
4 josh(1e+05, 10)   10 0.453 18.875 
5 josh(1e+06, 10)   10 5.381 224.208 

如此看來,他們都沒有太大的不同,但xts方法是somewh快於data.table方法。

+0

是。你能否在你的問題中加上「爲什麼」的答案?我猜你正在努力達到什麼樣的效果,因爲最終結果會比你想要的更好。 – John

+0

爲什麼?因爲我會與其他人分享這些數據,所以我想消除數字代表的含糊之處。 –

+0

0.334s vs 0.538s似乎是平均時間的微小差異。你確定這個結論是穩健的嗎?它包括在每個複製中一次又一次地創建數據的時間。在計算方法時,我看到的時間要短得多。 -1,現在總是可以稍後反轉。 –

回答

3

是的,xts包可以提供幫助。

首先,創建一個xts對象:

R> pt <- strptime(c("02/10/11 10:26:35 AM", "02/10/11 10:26:38 AM", 
+     "02/10/11 10:26:42 AM"), "%d/%m/%y %H:%M:%S %p", tz="UTC") 
R> vals <- c(0,1,0) 
R> x <- xts(vals, pt) 
R> x 
        [,1] 
2011-10-02 10:26:35 0 
2011-10-02 10:26:38 1 
2011-10-02 10:26:42 0 
Warning message: 
timezone of object (UTC) is different than current timezone(). 
R> 

我們可以忽略警告 - 我有一個美國的時區。

現在,我們可以從一開始就創建幾秒鐘的時間序列變量的末尾:

R> secs <- seq(start(x), end(x), by="1 sec") 

現在的魔術:通過合併我們原來的那個格的「空」的對象,我們擴展到gridL

R> x2 <- merge(x, xts(, secs)) 
R> x2 
        x 
2011-10-02 10:26:35 0 
2011-10-02 10:26:36 NA 
2011-10-02 10:26:37 NA 
2011-10-02 10:26:38 1 
2011-10-02 10:26:39 NA 
2011-10-02 10:26:40 NA 
2011-10-02 10:26:41 NA 
2011-10-02 10:26:42 0 
Warning message: 
timezone of object (UTC) is different than current timezone(). 

所有剩下的就是調用na.locf()

R> x2 <- na.locf(merge(x, xts(, secs))) 
R> x2 
        x 
2011-10-02 10:26:35 0 
2011-10-02 10:26:36 0 
2011-10-02 10:26:37 0 
2011-10-02 10:26:38 1 
2011-10-02 10:26:39 1 
2011-10-02 10:26:40 1 
2011-10-02 10:26:41 1 
2011-10-02 10:26:42 0 
Warning message: 
timezone of object (UTC) is different than current timezone(). 
R> 
3

這裏是你如何能做到這一點使用data.table包:

library(data.table) 

## Some example data 
X <- data.table(time = Sys.time() + c(0,3,7), val=c(0,1,0), key = "time") 

## A data.table with one row for each second spanned by X 
Y <- data.table(time = with(X, seq(min(time), max(time), by=1)), key = "time") 

## Merge them 
X[Y, rolltolast = TRUE] 
#     time val 
# 1: 2012-09-13 15:58:53 0 
# 2: 2012-09-13 15:58:54 0 
# 3: 2012-09-13 15:58:55 0 
# 4: 2012-09-13 15:58:56 1 
# 5: 2012-09-13 15:58:57 1 
# 6: 2012-09-13 15:58:58 1 
# 7: 2012-09-13 15:58:59 1 
# 8: 2012-09-13 15:59:00 0 
+0

同樣的結果,不同的工具。謝謝。 –

+0

@AndyBarbour好評。指出。 –