Как использовать lapply вместо цикла for? - PullRequest
0 голосов
/ 20 ноября 2018

Я пытаюсь рассчитать количество часов в интервале времени, который считается вечером (здесь, рассчитывается с 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 и учебников, которые я прочиталтам и вопросы, которые я читал в SO, до сих пор не помогли.Итак, может ли кто-нибудь помочь мне здесь, показывая мне, как бы вы достигли таких же результатов с lapply()?

1 Ответ

0 голосов
/ 20 ноября 2018

A 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"))
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...