2012-02-08 7 views
3

は、私は、次の間隔のいずれかに属するxサブセットdata.frame組合、複数の間隔は

intervals <- list(c(0.2, 0.8), c(1, 2), c(8, 8.2)) 

test <- function(range, x){ 
    which(x >= range[1] & x <= range[2]) 
} 

d[Reduce(`union`, lapply(intervals, test, x=d$x)), ] 

に基づいてサブセットを希望する次data.frame

d <- data.frame(x = seq(0, 10, length=100), value = rnorm(100)) 

を考えてみましょう、テスト機能は思わ冗長で、組み込みのfindIntervalのように見えますが、私はそれを使用するエレガントな方法を見つけることができません。

condition <- Reduce(`|`, lapply(lapply(intervals, findInterval, 
             x=d$x, all.inside=FALSE), `==`, 1)) 

d[condition, ] 

あなたはより良い提案することはできますか?

答えて

4
d[unlist(sapply(intervals, function(x) which(!is.na(cut(d$x,x))))),] 
      x  value 
3 0.2020202 0.15488314 
4 0.3030303 -0.06891842 
5 0.4040404 1.59909655 
6 0.5050505 0.31006866 
7 0.6060606 1.68986821 
8 0.7070707 0.18500635 
11 1.0101010 0.18721091 
12 1.1111111 0.32485063 
13 1.2121212 -0.42728405 
14 1.3131313 0.84220081 
15 1.4141414 -1.30745237 
16 1.5151515 -1.90335389 
17 1.6161616 -0.47139683 
18 1.7171717 0.01622827 
19 1.8181818 0.76362918 
20 1.9191919 -0.37827765 
81 8.0808081 0.46672521 
82 8.1818182 1.27038641 

編集:ここではfindInterval

d[findInterval(d$x,unlist(intervals))%%2==1,] 
+0

ありがとうございますが、「カット」は過度のように感じますか? – baptiste

+0

@baptiste OK、 'findInterval'ソリューションを追加しました – James

+0

いいです、それはまた' Reduce'の 'for'ループの必要性を取り除きます – baptiste

1

を使用して同じ結果がintervalsパッケージとソリューションです。それは間隔が片側に閉鎖され、他に開いていると仮定しているためfindInterval

d <- data.frame(x = seq(0, 10, length=100), value = rnorm(100)) 
intervals <- list(c(0.2, 0.8), c(1, 2), c(8, 8.2)) 
library(intervals) 
intervals <- Intervals(do.call(rbind, intervals)) 
intervals <- reduce(intervals) # Simplify, if they overlap 
condition <- distance_to_nearest(d$x, intervals) == 0 
# The following would allow for non-closed intervals, 
# but it is awfully slow. 
condition <- sapply(d$x, function(u) 
    any(!empty(interval_intersection(Intervals(c(u,u)), intervals)))) 
d[condition,] 

、それは、 をトリッキーかもしれません。 これが受け入れられる場合、間隔が順序付けされて重複しない場合、 は、間隔番号が奇数であるかどうかを確認するだけです。

intervals <- list(c(0.2, 0.8), c(1, 2), c(8, 8.2)) 
condition <- findInterval(d$x, unlist(intervals)) %% 2 == 1 
d[condition,] 
関連する問題