2017-12-08 8 views
1

私はdatetimeが開始日時と終了日時の間にあるかどうかを調べ、それに一致する値を返すかどうかを調べようとしています。それはdata.tableで動作しているが、DPLYRで動作させたい。あなたは日付時刻があれば2番目のテーブルの2つの日付の間に日付が返される場合

だから:

2017-07-01 02:15:00 
2017-07-01 02:30:00 

を第二のテーブルでこれらを調べる

begin,  end,       value1, value2 
2017-07-01 00:01:00, 2017-07-01 01:00:00, 1,  2 
2017-07-01 01:01:00, 2017-07-01 02:00:00, 3,  4 
2017-07-01 02:01:00, 2017-07-01 03:00:00, 5,  6 

リターン

date    value1 value2 
2017-07-01 02:15:00 5  6  
2017-07-01 02:30:00 5  6 

それは次のようになりますので、参照値の多くがあります。数百の検索日時。

これはdata.tableで動作しますが、多くのパッケージへの依存を減らすためにDPLYRを使用したいと考えています。これは私がこれまで持っているものです:私はのようなものを使用して考えていた

library(tidyverse) 
library(lubridate) 
library(data.table) 

dates <- read_csv("date1.csv") %>% 
    mutate(date = as_datetime(date)) 

lookup <- read_csv("lookup.csv") %>% 
    mutate(begin = as_datetime(begin), 
     end = as_datetime(end)) 

dates <- data.table(dates) 
lookup <- data.table(lookup) 
setkey(lookup, begin, end) 
dates[, c("begin", "end") := date] 
test.df <- foverlaps(dates, lookup)[, c("date", "value1", "value2"), 
             with = FALSE] 

dates <- structure(list(date = structure(c(1498867200, 1498868100, 1498869000, 
1498869900, 1498870800, 1498871700, 1498872600, 1498873500, 1498874400, 
1498875300, 1498876200, 1498877100, 1498878000, 1498878900, 1498879800, 
1498880700, 1498881600, 1498882500), tzone = "UTC", class = c("POSIXct", 
"POSIXt"))), .Names = "date", class = c("tbl_df", "tbl", "data.frame" 
), row.names = c(NA, -18L)) 

をルックアップテーブル:

test <- dates %>% rowwise() %>% 
    mutate(value1 = ifelse(lookup$begin >= date & date <= lookup$end, lookup$value1, "")) 

ここでは、ルックアップする日付です

lookup <- structure(list(begin = structure(c(1498867260, 1498870860, 1498874460, 
1498878060, 1498881660, 1498885260, 1498888860, 1498892460, 1498896060 
), class = c("POSIXct", "POSIXt"), tzone = "UTC"), end = structure(c(1498870800, 
1498874400, 1498878000, 1498881600, 1498885200, 1498888800, 1498892400, 
1498896000, 1498899600), class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
    value1 = c(1L, 3L, 5L, 7L, 9L, 11L, 13L, 15L, 17L), value2 = c(2L, 
    4L, 6L, 8L, 10L, 12L, 14L, 16L, 18L)), .Names = c("begin", 
"end", "value1", "value2"), class = c("tbl_df", "tbl", "data.frame" 
), row.names = c(NA, -9L)) 
+0

'foverlaps'ではなく' data.table'で非等価結合を使用し、 'rowwise'演算を行うことはその代わりにはなりません。 – eddi

+0

こんにちは、ありがとう、それはオプション2ですが、私はこれにDPLYRを使いたいと思います。私が考えていた1つのオプションは、データフレームをロングフォーマットに切り替え、それを15分ごとのdatetimeシーケンス(すべてのデータが4分の1時間であるため)に結合し、値を埋めてから別の結合を行います。これは可能ですが、私のアマチュアのコーディングでさえ混じっているようです。 –

答えて

0

以下を試すことができます。

library(tidyverse) 
library(lubridate) 

dates <- dates %>% 
    mutate(match_date = format(date, "%Y-%m-%d"), 
     match_hour = hour(date - minutes(1))) 

lookup <- lookup %>% 
    mutate(match_date = format(begin, "%Y-%m-%d"), 
     match_hour = hour(begin)) 


left_join(dates, lookup, by = c("match_date", "match_hour")) %>% 
    filter(date >= begin & date <= end) %>% 
    select(- match_date, - match_hour) %>% 
    head() 

# A tibble: 6 x 5 
#     date    begin     end value1 value2 
#    <dttm>    <dttm>    <dttm> <int> <int> 
# 1 2017-07-01 00:15:00 2017-07-01 00:01:00 2017-07-01 01:00:00  1  2 
# 2 2017-07-01 00:30:00 2017-07-01 00:01:00 2017-07-01 01:00:00  1  2 
# 3 2017-07-01 00:45:00 2017-07-01 00:01:00 2017-07-01 01:00:00  1  2 
# 4 2017-07-01 01:00:00 2017-07-01 00:01:00 2017-07-01 01:00:00  1  2 
# 5 2017-07-01 01:15:00 2017-07-01 01:01:00 2017-07-01 02:00:00  3  4 
# 6 2017-07-01 01:30:00 2017-07-01 01:01:00 2017-07-01 02:00:00  3  4 

まず、一致する日付と時刻を抽出します。 lookupテーブルの終了時刻としてdates表の日付から1分を差し引いて、時間が鋭い(つまり、01:00:00など)。私は最初の日に参加して、一致する時間(この場合は0)を取得したいので、分を差し引きます。

次に、私はleft_joindateslookupfilterをあなたの希望する基準で行います。

+0

こんにちは、コメントありがとうございます。実際のデータセットでは、ルックアップのデータが1時間以上、場合によっては1日以上に及ぶため、コードを変更してコードを変更すると機能し、1日か2日以上使用すると機能すると思います。 。これを達成する他の方法もあるように見えます。 –

+0

日付の範囲が数日以上に及ぶ場合には、記入されないデータがあるようです。 –

+0

ちょうど注記 - 複数の日の問題があるため、検索日時の15分のシーケンスに値をつけて検索したところ、NA値を埋めるために塗りつぶしを使用しました(以前のNA値は9999塗りつぶした後にNAに戻る)。これはちょうど私が探していた日付ファイルと結合されました。 –

関連する問題