2017-11-07 15 views
1

目的:あるデータフレームから別のデータフレームに日付をマップするには、特定の日付間隔内にあることが必要です。たとえば、20/12/2017から25/12/2017または26/12/2017から30/12/17までの時間間隔内に贈り物を配信する必要があるとします。 2013年12月23日私は、それが含まれる日付間隔に基づいて応答日を配置する場所を特定できる関数を作成したいと思います。上記の例では、応答日は20/20/2017から20/12/2017の間隔になります。 注:以下の「一致」という用語は、あるデータフレームから別のデータフレームに一定の条件が満たされたことを意味します。R:あるデータフレームの値を、関数を使った条件に基づいて別のデータフレームに置き換える方法は?

私が意味するものを示すためのサンプルコードです。

# Creating the Data Frame with a start and end date interval 
StartDate <- seq(as.Date("2000/1/1"), by = "month", length.out = 10) 

EndDate <- StartDate +7 

Dates_Interval <- data.frame(StartDate,EndDate) 

# Creating a second data frame with the response dates only 
ResponseDate <- seq(as.Date("2000/1/6"), by = "month", length.out = 10) 

Response_Substitute <- data.frame(ResponseDate) 
# Substituting random NA values 
Response_Substitute[c(1,5,8),] <- NA 


# > Response_Substitute 
#  ResponseDate 
# 1   <NA> 
# 2 2000-02-09 
# 3 2000-03-06 
# 4 2000-04-06 
# 5   <NA> 
# 6 2000-06-06 
# 7 2000-07-06 
# 8   <NA> 
# 9 2000-09-06 
# 10 2000-10-06 

# Creating a function which evaluates a value in data frame two    
# (Response_Substitute) and checks 
# whether it meets 
# a condition in Dates_Interval. 

dateresponses <- function(x,y,z) { 
    sub_date <- ifelse (y <=x && x <= z, x, NA) 
    converteddate <- as.Date(sub_date, origin = "1899-12-30") 
    return(converteddate) 
} 
# Example of the function in use to show how it matches a certain condition. 
x <- Response_Substitute[2,1] 
b <- dateresponses(x,Dates_Interval[2,1],Dates_Interval[2,2]) 


# > b 
# [1] "1930-02-04" 

# Example of the function in use to show when a response date does not 
# match a certain condition 
    x <- Response_Substitute[2,1] <- as.Date("2000/2/9") 
    b <- dateresponses(x,Dates_Interval[2,1],Dates_Interval[2,2]) 
# > b 
# [1] NA 

# Example of the function in use to show when there is no response date in  
# the Response_Substitute variable 
    x <- Response_Substitute[1,1] 
    b <- dateresponses(x,Dates_Interval[2,1],Dates_Interval[2,2]) 
# > b 
# [1] NA 

私はそれがStartDateEndDate列から内にある日付間隔で応答日付と一致するDates_Intervalデータフレームに新しい列を作成することができます機能を必要としています。一致するものがない場合、応答がない場合、応答はNAになります。回答がであるがである場合、応答の日付はどんな間隔にも収まらないので、比類のない応答をキャプチャするデータフレームを作成したい。

これは、最終的なデータフレームがどのように見えることができるものである:

Dates_Interval$ResponseDate <- Response_Substitute 
    # > Dates_Interval 
    # StartDate EndDate ResponseDate 
# 1 2000-01-01 2000-01-08   <NA> 
# 2 2000-02-01 2000-02-08 2000-02-06 
# 3 2000-03-01 2000-03-08 2000-03-06 
# 4 2000-04-01 2000-04-08 2000-04-06 
# 5 2000-05-01 2000-05-08   <NA> 
# 6 2000-06-01 2000-06-08 2000-06-06 
# 7 2000-07-01 2000-07-08 2000-07-06 
# 8 2000-08-01 2000-08-08   <NA> 
# 9 2000-09-01 2000-09-08 2000-09-06 
# 10 2000-10-01 2000-10-08 2000-10-06 

そしてないNAですが、別のデータフレームは次のように作成することができます任意の間隔と一致しない応答日のために:

Unmatched_Response_Date <- data.frame(seq(as.Date("2000/1/9"), by = "month", 
length.out = 2)) 

colnames(Unmatched_Response_Date) <- "Unmatched Responses" 

Unmatched_Response_Date 
# > Unmatched_Response_Date 
# Unmatched Responses 
# 1   2000-01-09 
# 2   2000-02-09 

編集dateresponses機能を使用しているときに私が気づいたバグがあります。 Response_substituteデータフレームの日付を使用するとします。日付の出力はデータフレームと同じではありません。例えばResponse_substitute[2,1]の場合、値は2000-02-09である必要がありますが、代わりに1930-02-04となります。この問題を解決するためのアイデアもありますか?ここで

+0

あなたの関数の 'ifelse'内で' 'N/A" 'の代わりに' 'NA'を使用しないのはなぜですか?これはエラーの例のエラーメッセージの代わりに 'NA'を返します。 – LAP

+1

@LAPそれは大きなポイントです!制限事項を整理するコードに変更します。これは私たちが全体的な問題を解決するのに役立ちます、ありがとうございます。 – MrReference

+0

https://stackoverflow.com/questions/21560500/data-table-merge-based-on-date-ranges。それに似た考えがあるようです。必要に応じて、私はあなたの特定の問題に対する回答を書くことができます。 – jacobsg

答えて

0

は、あなたが提供するコードは次のとおりです。我々は両方のdata.framesで間隔を有するように

StartDate <- seq(as.Date("2000/1/1"), by = "month", length.out = 10) 
EndDate <- StartDate +7 
Dates_Interval <- data.frame(StartDate,EndDate) 
# Creating a second data frame with the response dates only 
ResponseDate <- seq(as.Date("2000/1/6"), by = "month", length.out = 10) 
Response_Substitute <- data.frame(ResponseDate) 
# Substituting random NA values 
Response_Substitute[c(1,5,8),] <- NA 

だから、質問に答えるために、私は別の日付列を追加しました。また、レスポンスを含む最初のdata.frameからNA値を削除しました。これらはあなたの期待される出力には関係していないようです。間違っていれば私を正す。

Response_Substitute$Date2 <- Response_Substitute$ResponseDate - 1 
Response_Substitute <- Response_Substitute[!is.na(Response_Substitute$ResponseDate),] 

この質問の核心はfoverlaps()と呼ばれるdata.table機能を使用してダウンしています。ドキュメントから、これは高速重複結合関数です。これは、2つの区間が重なる場所を見つけて、データを一緒に結合するように設計されています。以下のコードはそれだけです。

これは、私がResponse_Substituteに他の日付を生成する必要があった理由です。 foverlaps()2つの間隔が必要です。

library(data.table) 
Dates_Interval <- as.data.table(Dates_Interval) 
Response_Substitute <- as.data.table(Response_Substitute) 
setkey(Response_Substitute, Date2, ResponseDate) 
join_df <- foverlaps(Dates_Interval, Response_Substitute, 
      by.x = c('StartDate', 'EndDate')) 

出力:

ResponseDate  Date2 StartDate EndDate 
1:   <NA>  <NA> 2000-01-01 2000-01-08 
2: 2000-02-06 2000-02-05 2000-02-01 2000-02-08 
3: 2000-03-06 2000-03-05 2000-03-01 2000-03-08 
4: 2000-04-06 2000-04-05 2000-04-01 2000-04-08 
5:   <NA>  <NA> 2000-05-01 2000-05-08 
6: 2000-06-06 2000-06-05 2000-06-01 2000-06-08 
7: 2000-07-06 2000-07-05 2000-07-01 2000-07-08 
8:   <NA>  <NA> 2000-08-01 2000-08-08 
9: 2000-09-06 2000-09-05 2000-09-01 2000-09-08 
10: 2000-10-06 2000-10-05 2000-10-01 2000-10-08 

最後のステップは、列を削除し、非マッチの空のベクターを生成することです。

# Removes the Date2 Column 
join_df[, Date2:=NULL] 
# Generate list of responses that didn't join 
setdiff(Response_Substitute$ResponseDate, join_df$ResponseDate) 

これは問題が解決しますか? さらに読む:12

関連する問題