設置數據
首先設置輸入數據幀。我們創建一個數據幀的兩個版本:A
和B
只使用字符列的時間和At
和Bt
使用克隆氏病包"times"
類的時間(其中有超過"character"
類的優點是可以添加和減去它們):
LinesA <- "OBS ID StartTime Duration Outcome
1 01 10:12:06 00:00:10 Normal
2 02 10:12:30 00:00:30 Weird
3 01 10:15:12 00:01:15 Normal
4 02 10:45:00 00:00:02 Normal"
LinesB <- "OBS ID Time
1 01 10:12:10
2 01 10:12:17
3 02 10:12:45
4 01 10:13:00"
A <- At <- read.table(textConnection(LinesA), header = TRUE,
colClasses = c("numeric", rep("character", 4)))
B <- Bt <- read.table(textConnection(LinesB), header = TRUE,
colClasses = c("numeric", rep("character", 2)))
# in At and Bt convert times columns to "times" class
library(chron)
At$StartTime <- times(At$StartTime)
At$Duration <- times(At$Duration)
Bt$Time <- times(Bt$Time)
sqldf與次類
現在我們可以使用sqldf包進行計算。我們使用method="raw"
(不分配類輸出),所以我們必須在"times"
類分配給輸出"Time"
列我們自己:
library(sqldf)
out <- sqldf("select Bt.OBS, ID, Time, Outcome from At join Bt using(ID)
where Time between StartTime and StartTime + Duration",
method = "raw")
out$Time <- times(as.numeric(out$Time))
結果是:
> out
OBS ID Time Outcome
1 1 01 10:12:10 Normal
2 3 02 10:12:45 Weird
隨着開發版本sqldf這樣做可以不用method="raw"
而"Time"
列會自動設置爲"times"
class by sqldf class assignment heuristic:
library(sqldf)
source("http://sqldf.googlecode.com/svn/trunk/R/sqldf.R") # grab devel ver
sqldf("select Bt.OBS, ID, Time, Outcome from At join Bt using(ID)
where Time between StartTime and StartTime + Duration")
sqldf與字符類
它實際上可能不通過執行sqlite的所有時間計算出使用的SQLite的strftime函數的字符串使用"times"
類。 SQL語句是可惜稍稍更復雜:
sqldf("select B.OBS, ID, Time, Outcome from A join B using(ID)
where strftime('%s', Time) - strftime('%s', StartTime)
between 0 and strftime('%s', Duration) - strftime('%s', '00:00:00')")
編輯:
了一系列固定的語法,增加了額外的方法和固定/改善read.table
聲明的修改。
編輯:
簡體/改進最終sqldf聲明。
哇。謝謝你這樣徹底的回答。 – bnjmn