我想知道是否有辦法將一個函數應用於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
和分佈在那些日子裏,事件的數量。我第一次嘗試這樣做是這樣的:
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)
然而,這是不可能的,因爲apply
電話as.matrix
上test
,因而它被轉換爲字符矩陣和所有列類都將丟失。
我已經找到了兩個解決方法,你可以在下面找到,所以我的問題更具哲學性。
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)
,這將工作?
如果你想保留這個類,使用'lapply'循環遍歷行的順序,而不是'apply' – akrun
@akrun謝謝你的建議,但是這不正是我在「解決方法2」中所做的嗎?如果沒有請詳細說明你的意思。謝謝! – AEF
是的,你是對的。我用'data.table'發佈了一個解決方案。請檢查是否使它更好 – akrun