我正在尝试计算一个被认为是晚上的时间间隔中的小时数(此处从16:00开始计算)。下面是一个示例。
start end evening
1 2018-01-01 10:47:05 2018-01-01 16:36:03 0.600924
2 2018-01-02 04:05:56 2018-01-02 14:24:59 0.000000
3 2018-01-02 13:37:41 2018-01-03 00:47:31 5.000000
4 2018-01-02 22:53:31 2018-01-03 04:43:59 0.000000
5 2018-01-03 17:04:20 2018-01-03 22:27:39 3.927569
我创建了一个函数f_overlap()
,用于计算每行的傍晚小时数。在for
循环中运行它看起来像这样:
library(lubridate)
...
for (row in 1:nrow(df)) {
df$evening[row] <- f_overlap(eveningStart,
eveningEnd,
interval(df[row,'start'], df[row,'end']))
}
我无法使用lapply()
而不是for
循环,而且我在那儿读到的教程以及在那儿读到的问题都没有到目前为止没有任何帮助。因此,有人可以在这里帮助我,向我展示如何使用lapply()
获得相同的结果吗?
答案 0 :(得分:0)
sapply()
应该很合适。
evening <- sapply(1:nrow(df1), f_overlap)
> cbind(df1, evening=evening)
start end evening
1 2018-01-01 10:47:05 2018-01-01 16:36:03 0.6008333
2 2018-01-02 04:05:56 2018-01-02 14:24:59 0.0000000
3 2018-01-02 13:37:41 2018-01-03 00:47:31 5.0000000
4 2018-01-02 22:53:31 2018-01-03 04:43:59 0.0000000
5 2018-01-03 17:04:20 2018-01-03 22:27:39 3.9277778
如果您依赖lapply()
,则必须unlist()
或rbind()
输出:
do.call(rbind, lapply(1:nrow(df1), f_overlap)) # rbind, or
unlist(lapply(1:nrow(df1), f_overlap)) # unlist
您也可以在上面的cbind()
中使用这两种选择。
我试图重新构造您的f_overlap()
函数的作用,这些值至少非常相似。
f_overlap <- function(x) {
i0 <- as.POSIXct(paste(as.character(as.Date(df1[x,]$start)), "16:00"))
t0 <- df1[x, ]$start
t1 <- df1[x, ]$end
i1 <- as.POSIXct(paste(as.character(as.Date(df1[x,]$start)), "21:00"))
if (t0 < i0 & t1 < i0) return(0)
else if (t0 < i0 & t1 > i1) return(5)
else if (t0 > i1 & t1 > i1) return (0)
else if (t0 > i0 & t1 < i1)
return(difftime(t1, t0, units="hours"))
else if (t0 < i0 & t1 < i1)
return(difftime(t1, i0, units="hours"))
else if (t0 > i0 & t1 > i1)
return(difftime(i1, t0, units="hours"))
}