3

unionそれ自体が間隔ではない共用体を処理できる for 時間間隔の実装を探しています。

lubridate時間間隔の関数が含まれていることに気付きunionましたが、ユニオンが間隔でない場合でも、常に単一の間隔を返します (つまり、両方の開始日の最小値と両方の終了日の最大値によって定義された間隔を返します。いずれかの間隔でカバーされます):

library(lubridate)
int1 <- new_interval(ymd("2001-01-01"), ymd("2002-01-01"))
int2 <- new_interval(ymd("2003-06-01"), ymd("2004-01-01"))
union(int1, int2)
# Union includes intervening time between intervals.
# [1] 2001-01-01 UTC--2004-01-01 UTC

パッケージも見ましたintervalが、そのドキュメントにはunion.

私の最終目標は、複雑な結合を%within%次のように使用することです。

my_int %within% Reduce(union, list_of_intervals)

したがって、具体的な例を考えると、次のようになりますlist_of_intervals

[[1]] 2000-01-01 -- 2001-01-02 
[[2]] 2001-01-01 -- 2004-01-02 
[[3]] 2005-01-01 -- 2006-01-02 

my_int <- 2001-01-01 -- 2004-01-01そうではないので返すべきであり%within%、そうあるべきです。list_of_intervalsFALSEmy_int <- 2003-01-01 -- 2006-01-01TRUE

ただし、複雑な結合にはこれ以外にも用途があると思います。

4

2 に答える 2

3

私があなたの質問を正しく理解していれば、入力セットの最小値と最大値にまたがる単一の間隔だけではなく、重複する可能性のある一連の間隔から始めて、入力セットの UNION を表す間隔のリストを取得したいと考えています。 . これは私が持っていたのと同じ質問です。

同様の質問が次の場所で行われました:区間の和合

...しかし、受け入れられた応答は、間隔が重複して失敗します。ただし、hosolmaz (私は SO を初めて使用するため、このユーザーにリンクする方法がわからない) が問題を修正する修正を (Python で) 投稿し、それを次のように R に変換しました。

library(dplyr) # for %>%, arrange, bind_rows

interval_union <- function(input) {
  if (nrow(input) == 1) {
    return(input)
  }
  input <- input %>% arrange(start)
  output = input[1, ]
  for (i in 2:nrow(input)) {
    x <- input[i, ]
    if (output$stop[nrow(output)] < x$start) {
      output <- bind_rows(output, x)
    } else if (output$stop[nrow(output)] == x$start) {
      output$stop[nrow(output)] <- x$stop
    }
    if (x$stop > output$stop[nrow(output)]) {
      output$stop[nrow(output)] <- x$stop
    }
  }
  return(output)
}

重複する間隔と連続しない間隔を使用した例では、次のようになります。

d <- as.data.frame(list(
  start = c('2005-01-01', '2000-01-01', '2001-01-01'),
  stop = c('2006-01-02', '2001-01-02', '2004-01-02')),
  stringsAsFactors = FALSE)

これにより、次が生成されます。

> d
       start       stop
1 2005-01-01 2006-01-02
2 2000-01-01 2001-01-02
3 2001-01-01 2004-01-02

> interval_union(d)
       start       stop
1 2000-01-01 2004-01-02
2 2005-01-01 2006-01-02

私はRプログラミングの初心者なので、上記のinterval_union()関数を変換して、入力データフレームだけでなく、使用する「開始」および「停止」列の名前もパラメーターとして受け入れることができれば、関数もっと簡単に再利用できるかもしれません。それは素晴らしいことです。

于 2016-11-09T14:05:41.087 に答える
2

さて、あなたが提供した例では、 と の結合はint1int22 つの間隔を持つベクトルとして見ることができます。

int1 <- new_interval(ymd("2001-01-01"), ymd("2002-01-01"))
int2 <- new_interval(ymd("2003-06-01"), ymd("2004-01-01"))
ints <- c(int1,int2)

%within%ベクトルで動作するので、次のようなことができます:

my_int <- new_interval(ymd("2001-01-01"), ymd("2004-01-01"))
my_int %within% ints
# [1]  TRUE FALSE

したがって、間隔がリストの間隔のいずれかに含まれているかどうかを次のように確認できますany

any(my_int %within% ints)
# [1] TRUE

あなたのコメントは正しい%within%です。

a が間隔の場合、TRUE を返すには、開始日と終了日の両方が b 内にある必要があります。

a と b が両方とも間隔である場合のソース コードを見る%within% と、次のように思われます。

setMethod("%within%", signature(a = "Interval", b = "Interval"), function(a,b){
    as.numeric(a@start) - as.numeric(b@start) <= b@.Data & as.numeric(a@start) - as.numeric(b@start) >= 0
})

したがって、 の開始点のみaが に対してテストされb、結果と一貫しているように見えます。多分これはバグと見なされ、報告されるべきですか?

于 2013-02-15T08:28:08.007 に答える