2016-04-25 4 views
1

R-方法は:カウント私はこの形式のデータフレーム<code>df</code>を持っているRで

a b id 
1 2 1234758 
1 1 1234758 
3 5 1234759 
5 5 1234759 
5 5 1234759 
2 2 1234760 

私は、各id値についてdf$adf$b間の変化を観察する回数をカウントします。私はその後、

summary <- as.data.frame(table(df$id)) 
id n_id 
2 1234758 
3 1234759 
1 1234760 

をした私はIDごとに倍のaとbの変化の数を計算するためにこれを書いただけでなくIDのいくつかの数字に興味を持っていますので

(両方dfsummaryが順にソートされていますdfに各IDが表示される時間の数を各エントリを調べid

summary$jumps <- 0 
k <- 1 
for(i in 1:nrow(summary)) { 
n <- summary$n_id[i] 
for(j in k:k+n-1) if(df$a[j] != df$b[j]) summary$jumps[i] <- summary$jumps[i] + 1 
    k <- k + n 
} 

、及びBをチェックし、要約内の適切なエントリを更新します。これは意図したとおりに動作しますが、それは私には遅く見えます。

私はRをかなり新しくしていますが、Rでこれを行うより効率的な方法は何でしょうか?このコードをどのようにベクトル化しますか?データフレームには約3千万の行があります。

+1

からaggregateを使用することができます ' – akrun

+0

ラブリー、この(CBIND(=!= B)〜ID、DF1、FUN =合計ジャンプ)を見える下の答えに反して、何とか私の観察の3分の1を落とした。また、これには追加のパッケージやdata.tableの変換が必要ないことも嬉しいです。あなたがそれを答えにしたら、これを選ぶだろう。 –

+0

コメントのTHanks。それを解決策として掲示します。 – akrun

答えて

1

我々は、ベースR` `集計`でbase R

aggregate(cbind(jumps = a!=b)~id, df1, FUN=sum) 
+0

私は同じグループを削除したい場合、同じソリューションを適用したい場合は(つまり、IDを持つすべてのエントリ)別のパラメータ、日付)にはnaが含まれていましたか? –

+0

@ThreeDiag記事を – akrun

+0

に更新してください。私はループでそれを実現することができました。私は新しい質問をするでしょう:) –

4

私が問題を正しく理解していれば、data.tableを使ってかなり簡単に解決できます。

library(data.table) 

dt = setDT(df)     # Create a data table 
dt[,list(jumps=sum(a!=b)),by=id] # Sum rows where a!=b grouped by id 

#   id jumps 
# 1: 1234758  1 
# 2: 1234759  1 
# 3: 1234760  0 
+0

問題があるようです。 'summary < - dt [、list ...]'の行数を数えると 'length(unique(df $ id)) 'とまったく同じであると思うでしょうが、それはいくつかのIDがプロセスで消えて見える? –

+0

IDは私が上記の投稿に書いたものよりも長いからでしょうか?私はそれが違いがなかったと思ったが、実際には14桁の長さです –

関連する問題