2

多くのエントリを持つデータセットがあります。これらの各エントリは特定の ID (belongID) に属し、エントリは (uniqID で) 一意ですが、同じソース (sourceID) から複数のエントリを取得できます。同じソースからの複数のエントリが同じ所属 ID を持つことも可能です。データセットで行う必要がある調査のために、1 つの所属 ID に対して 5 回以上発生する単一の sourceID のエントリを削除する必要があります。保持する必要がある最大 5 つのエントリは、「時間」値が最も高いエントリです。

これを説明するために、次のサンプル データセットがあります。

   belongID   sourceID uniqID   Time     
   1           1001     101       5            
   1           1002     102       5        
   1           1001     103       4        
   1           1001     104       3       
   1           1001     105       3     
   1           1005     106       2        
   1           1001     107       2       
   1           1001     108       2       
   2           1005     109       5                
   2           1006     110       5        
   2           1005     111       5        
   2           1006     112       5        
   2           1005     113       5      
   2           1006     114       4        
   2           1005     115       4        
   2           1006     116       3       
   2           1005     117       3                
   2           1006     118       3       
   2           1005     119       2        
   2           1006     120       2        
   2           1005     121       1      
   2           1007     122       1        
   3           1010     123       5        
   3           1480     124       2  

最終的な例は次のようになります。

   belongID   sourceID uniqID   Time     
   1           1001     101       5            
   1           1002     102       5        
   1           1001     103       4        
   1           1001     104       3       
   1           1001     105       3     
   1           1005     106       2        
   1           1001     107       2           
   2           1005     109       5                
   2           1006     110       5        
   2           1005     111       5        
   2           1006     112       5        
   2           1005     113       5      
   2           1006     114       4        
   2           1005     115       4        
   2           1006     116       3       
   2           1005     117       3                
   2           1006     118       3           
   2           1007     122       1        
   3           1010     123       5        
   3           1480     124       2     

ファイルにはデータ エントリを含むさらに多くの列がありますが、選択は純粋に時間に基づく必要があります。例に示すように、同一の属する ID を持つ sourceID の 5 番目と 6 番目のエントリが同じ時刻を持つことも発生する可能性があります。この場合、最大 = 5 であるため、選択する必要があるのは 1 つだけです。

ここでのデータセットは、説明のために、所属 ID と時間で適切に並べられていますが、実際のデータセットではそうではありません。この問題に取り組む方法はありますか?私はまだ似たようなものに出くわしていません..

4

5 に答える 5

1

plyrパッケージを使用した 2 行のソリューション:

library(plyr)
x <- ddply(dat, .(belongID, sourceID), function(x)tail(x[order(x$Time), ], 5))
xx <- x[order(x$belongID, x$uniqID), ]

結果:

   belongID sourceID uniqID Time
5         1     1001    101    5
6         1     1002    102    5
4         1     1001    103    4
2         1     1001    104    3
3         1     1001    105    3
7         1     1005    106    2
1         1     1001    108    2
10        2     1005    109    5
16        2     1006    110    5
11        2     1005    111    5
17        2     1006    112    5
12        2     1005    113    5
15        2     1006    114    4
9         2     1005    115    4
13        2     1006    116    3
8         2     1005    117    3
14        2     1006    118    3
18        2     1007    122    1
19        3     1010    123    5
20        3     1480    124    2
于 2012-05-29T12:02:17.613 に答える
1

datあなたのデータフレームの場合:

do.call(rbind, 
        by(dat, INDICES=list(dat$belongID, dat$sourceID), 
           FUN=function(x) head(x[order(x$Time, decreasing=TRUE), ], 5)))
于 2012-05-29T12:04:40.683 に答える
1

データが にあるとしdfます。順序付けられた (uniqID による) 出力は、この後に取得されます。

tab <- tapply(df$Time, list(df$belongID, df$sourceID), length)
bIDs <- rownames(tab)
sIDs <- colnames(tab)
for(i in bIDs)
{
    if(all(is.na(tab[bIDs == i, ])))next
    ids <- na.omit(sIDs[tab[i, sIDs] > 5])
    for(j in ids)
    {
        cond <- df$belongID == i & df$sourceID == j
        old <- df[cond,]
        id5 <- order(old$Time, decreasing = TRUE)[1:5]
        new <- old[id5,]
        df <- df[!cond,]
        df <- rbind(df, new)
    }
}
df[order(df$uniqID), ]
于 2012-05-29T11:37:49.747 に答える
0

このメソッドが使用されるデータセットには、170.000以上のエントリとほぼ30の列があります

私のデータセットを使用して、danas.zuokas、mplourde、Andrieによって提供された3つのソリューションのそれぞれをベンチマークすると、次の結果が得られました。

danas.zuokasのソリューション:

   User     System  Elapsed 
   2829.569   0     2827.86

mplourdeのソリューション:

   User     System  Elapsed 
   765.628  0.000   763.908

Aurdieのソリューション:

   User     System  Elapsed 
   984.989  0.000   984.010

したがって、mplourdeのソリューションを使用します。皆さん、ありがとうございました!

于 2012-05-29T22:08:13.067 に答える
0

これは、次を使用して高速化する必要がありますdata.table

DT = as.data.table(dat)

DT[, .SD[tail(order(Time),5)], by=list(belongID, sourceID)]

余談:この質問に対するさまざまな回答で同じ変数名が繰り返される回数を数えることを提案します。長い名前や類似したオブジェクト名がたくさんありますか?

于 2012-05-30T09:49:11.153 に答える