2016-05-31 5 views
0

私はデータセットをフィルタリングするために書いたタップ関数を適用しようとしています。以下に、私がしようとしていることを説明するためのサンプルデータフレーム(df)を示します。タップ関数の結果によるデータフレームのフィルタリング

私はdf $ Cumulative_Timeの値が14の値に最も近い行をデータフレーム内に保持したいと考えています。の場合はそれぞれの因子レベル(値が最も近い値を保持する14 IDファクターごとに)。

ID Date Results TimeDiff Cumulative_Time 
A 7/10/2015 71 0 0 
A 8/1/2015 45 20 20 
A 8/22/2015 0 18 38 
A 9/12/2015 79 17 55 
A 10/13/2015 44 26 81 
A 11/27/2015 98 37 118 
B 7/3/2015 75 0 0 
B 7/24/2015 63 18 18 
B 8/21/2015 98 24 42 
B 9/26/2015 70 30 72 
C 8/15/2015 77 0 0 
C 9/2/2015 69 15 15 
C 9/4/2015 49 2 17 
C 9/8/2015 88 2 19 
C 9/12/2015 41 4 23 
C 9/19/2015 35 6 29 
C 10/10/2015 33 18 47 
C 10/14/2015 31 3 50 
D 7/2/2015 83 0 0 
D 7/28/2015 82 22 22 
D 8/27/2015 100 26 48 
D 9/17/2015 19 17 65 
D 10/8/2015 30 18 83 
D 12/9/2015 96 51 134 
D 1/6/2016 30 20 154 
D 2/17/2016 32 36 190 
D 3/19/2016 42 27 217 

私は限り、次のようだ:

spec_day = 14 # value I want to compare df$Cumulative_Time to 


# applying function to calculate closest value to spec_day 
    tapply(df$Cumulative_Time, df$ID, function(x) which(abs(x - spec_day) == min(abs(x - spec_day)))) 

は質問:どのように私は私のデータフレームDFのフィルタリングを行うための手段として、このtapply機能が含まれていますか?私はこの問題に正しい方法で近づいていますか、これを達成するための簡単な方法はありますか?どんな助けもありがとう - ありがとう!ここで

+0

あなたがRの基本言語に固執したい場合は、 'と'そして 'スプリット(DF、DF $ ID)を見てすることができますlapplyは特定のID 'result < - lapply(mysplit、FUN = function(df){df [which()...]])'に対応するインデックスを取得するためにあなたのアプローチを使います。最後に、すべてのフィルタリングされたデータを 'do.call(" rbind "、result)'と組み合わせます。私は 'data.table'オプションを調べることをお勧めします –

+0

ありがとう、@ EricLecoutre!私はsplit()について読むことを覚えているので、この方法も試してみよう! – soitgoes

答えて

2

は、私がtapplyを使用していないことに注意してください、あなたはそれを行うことができます方法です。

spec_day <- 14 
new_df <- do.call('rbind', 
      by(df, df$ID, 
      FUN = function(x) x[which.min(abs(x$Cumulative_Time - spec_day)), ] 
      )) 
new_df 

    ID  Date Results TimeDiff Cumulative_Time 
A A 8/1/2015  45  20    20 
B B 7/24/2015  63  18    18 
C C 9/2/2015  69  15    15 
D D 7/28/2015  82  22    22 

which.min(およびその兄弟which.max)非常に便利な機能です。ここで

+0

ありがとう、@bouncyball!私はwhich.minを理解していると思う - この機能に私を指摘してくれてありがとう、この問題の別のアプローチに私を紹介してくれてありがとう! – soitgoes

1

data.tableを使用して、より簡潔かつ迅速に代替です:

library(data.table) 
setDT(df)[, .SD[which.min(abs(Cumulative_Time - 14))], by = ID] 
# ID  Date Results TimeDiff Cumulative_Time 
#1: A 8/1/2015  45  20    20 
#2: B 7/24/2015  63  18    18 
#3: C 9/2/2015  69  15    15 
#4: D 7/28/2015  82  22    22 
+0

ありがとう、@mtoto!私はこの1つの簡潔さが好きです。コードが何をしているのかを理解することは、かなり直感的です! – soitgoes

関連する問題