data.frameの各行に関数を適用して列クラスを保存する方法があるのだろうか?のは、私が何を意味するか明確にする例を見てみましょう:data.frameの各行に関数を適用し、列クラスを保持する
test <- data.frame(startdate = as.Date(c("2010-03-07", "2013-09-13", "2011-11-12")),
enddate = as.Date(c("2010-03-23", "2013-12-01", "2012-01-05")),
nEvents = c(123, 456, 789))
は、私がstartdate
とenddate
間のすべての日を挿入することにより、data.frame test
を拡張したもの日間のイベントの数を配布したいとします。これを行うには私の最初の試みは、これだった:apply
はtest
にas.matrix
を呼び出すので、それが文字行列に変換されると、すべての列クラスが失われているため
eventsPerDay1 <- function(row) {
n_days <- as.numeric(row$enddate - row$startdate) + 1
data.frame(date = seq(row$startdate, row$enddate, by = "1 day"),
nEvents = rmultinom(1, row$nEvents, rep(1/n_days, n_days)))
}
apply(test, 1, eventsPerDay1)
これは、しかし、ことはできません。
私はすでに下記の2つの回避策を見つけました。私の質問は、より哲学的なものです。
library(magrittr)
############# Workaround 1
eventsPerDay2 <- function(startdate, enddate, nEvents) {
n_days <- as.numeric(enddate - startdate) + 1
data.frame(date = seq(startdate, enddate, by = "1 day"),
nEvents = rmultinom(1, nEvents, rep(1/n_days, n_days)))
}
mapply(eventsPerDay2, test$startdate, test$enddate, test$nEvents, SIMPLIFY = F) %>%
do.call(rbind, .)
############# Workaround 2
seq_along(test) %>%
lapply(function(i) test[i, ]) %>%
lapply(eventsPerDay1) %>%
do.call(rbind, .)
回避策と私の「問題」は以下の通りです:
- 対処方法1:それは最高の理由ではないかもしれないが、私は単に
mapply
が好きではありません。それは他の*apply
関数とは異なる署名(引数の順序が異なるため)があり、私は常にfor
というループがより明確になったと感じています。 - 回避策2:非常に柔軟性がありますが、何が起きているのかは一目瞭然ではないと私は考えています。
だから誰でも、コールがapply(test, 1, eventsPerDay1)
のようになり、それが機能することは知っていますか?
クラスを保存したい場合は、 'apply'ではなく' apply'ではなく 'lapply'ループを使用してください。提案のおかげで – akrun
@akrunに感謝しますが、"回避策2 "で行ったこととまったく同じですか?そうでない場合は、あなたが意味することを詳しく教えてください。ありがとう! – AEF
はい、そうです。私は 'data.table'を使って解決策を投稿しました。それがより良いことを確認してください。 – akrun