私はRで大きなデータフレームを持っており、既存の列に基づいていくつかの新しい列を作成したいと思います。ただし、各行について、新しい値は他の行にも依存します。ここで従属サブセットの大きなデータフレームの各行の複数の新しい集計
は私が何をしたいのか、いくつかのダミーデータ
colnames <- c('date', 'docnr', 'clientid', 'values')
docnr <- c(1,2,3,4,5,6)
dates <- c('2017-01-01', '2017-02-01', '2017-03-01', '2017-04-01','2017-01-05', '2017-02-05')
clients <- c(1,1,1,1,2,2)
values <- c(10,14,4,7,9,19)
df <- data.frame(cbind(dates, docnr, clients, values))
names(df) <- colnames
df$date <- as.Date(df$date, format = "%Y-%m-%d")
df
date docnr clientid values
1 2017-01-01 1 1 10
2 2017-02-01 2 1 14
3 2017-03-01 3 1 4
4 2017-04-01 4 1 7
5 2017-01-05 5 2 9
6 2017-02-05 6 2 19
です(一意docnrによって識別される)すべての行は、日付とクライアントIDを取り、持っている他のすべての行を探して、あります同じクライアントID、およびより早い日付。
次に、このサブセットからいくつかのものを計算したいと思います。たとえば、このサブセットの合計行数と、このサブセットのすべての値の合計が必要です。
したがって、この例のデータのために、私が期待する:
date docnr clientid values counts totals
1 2017-01-01 1 1 10 0 0
2 2017-02-01 2 1 14 1 10
3 2017-03-01 3 1 4 2 24
4 2017-04-01 4 1 7 3 28
5 2017-01-05 5 2 9 0 0
6 2017-02-05 6 2 19 1 9
瞬間、私はforループを使用します。
counts <- numeric(0)
totals <- numeric(0)
for (i in 1:nrow(df)) {
tmp <- df[df$date< df$date[i] & df$clientid== df$clientid[i],
c("date", "docnr","value")]
cnt <- nrow(tmp)
tot <- sum(tmp$value)
counts[i] <- res
totals[i] <- tot
}
df$counts <- counts
df$totals <- totals
このループは、700Kの行のデータフレームのために明らかに非常に遅いです(まだ完了までにそれを実行していない)。 doSNOW
を使った並列実装は、はるかに優れた縮尺ではないようです。
sqldf
のSQLクエリを使用しようとしましたが、サブクエリは一度に1つの値しか返せません。これは、定義したいすべての新しい列に対してクエリを実行することを意味します(さらに、後の派生列)。
私はSQLオブジェクト(Is it possible to get multiple values from a subquery?)で解決策を見つけましたが、オブジェクトはRのsqldfでは機能しませんでした。 2番目のクエリは最初のクエリの情報を持つ必要があるため、結合の使用は機能しません。
私はRで始まったばかりです(SQLにもあまりよく慣れていません)ので、これを行うより効率的な方法を誰かが知っていれば、私は非常に義務づけられます。
をしたいデータが含まれていますすべての要素を文字に強制するので、.frame'を使用します。代わりに 'data.frame'を直接使用してください:' df
lmo