Рассчитать среднее количество дней за пребывание в каждом месте, в месяц - dplyr - PullRequest
1 голос
/ 04 октября 2019

Я рассчитываю эффективно рассчитать среднее время за пребывание, за месяц и за местоположение. Например, среднее пребывание в Loc1 в январе составляет 1,5 дня. У меня есть следующая таблица

Date.p1 <- c(c(timeBasedSeq("2019-01-01::2019-01-07")), c(timeBasedSeq("2019-01-01::2019-01-07")))
Character.p1 <- c(c(replicate(7, "Paul")), c(replicate(7, "Ellen")))
Location.p1 <-
  c("Loc.1", "Loc.1", "Loc.2", "Loc.2", "Loc.2", "Loc.2","Loc.1", "Loc.2", "Loc.2", "Loc.2", "Loc.3","Loc.3","Loc.2","Loc.2")

df.p1 <- as.data.frame(cbind(as.character(Date.p1), Character.p1, Location.p1))

           V1 Character.p1 Location.p1
1  2019-01-01         Paul       Loc.1
2  2019-01-02         Paul       Loc.1
3  2019-01-03         Paul       Loc.2
4  2019-01-04         Paul       Loc.2
5  2019-01-05         Paul       Loc.2
6  2019-01-06         Paul       Loc.2
7  2019-01-07         Paul       Loc.1
8  2019-01-01        Ellen       Loc.2
9  2019-01-02        Ellen       Loc.2
10 2019-01-03        Ellen       Loc.2
11 2019-01-04        Ellen       Loc.3
12 2019-01-05        Ellen       Loc.3
13 2019-01-06        Ellen       Loc.2
14 2019-01-07        Ellen       Loc.2

Я рассчитываю эффективно рассчитать среднее время пребывания, месяца и места. Например, среднее пребывание в Loc1 в январе составляет 1,5 дня.

Я построил решение, но оно не выглядит как R-esque.

df.p1 <- unfactor(df.p1)
df.p1$V1 <- as.Date(df.p1$V1)
df.p1$Stay.id <- 0
df.p1$Month <- months(df.p1$V1)
id.num <- 1

Создание идентификатора пребывания для изоляции пребывания второго, третьего и n-го пребывания

for (i in 1:nrow(df.p1)){
      if( i == 1) {
        df.p1[i,4] <- id.num
        id.num <- id.num + 1
      } else {
        if (df.p1[i,3] == df.p1[i - 1,3]){
          df.p1[i,4] <- df.p1[i - 1,4]
        } else {
          df.p1[i,4] <- id.num
          id.num <- id.num + 1

        }
      }
    }

Количество ночей за пребывание

df.p2 <- df.p1 %>% dplyr::group_by(Stay.id, Month) %>%
  summarise(Stay.length = n())


Location.Stay.id.Recon <- df.p1 %>% dplyr::select(Location.p1, Stay.id)  %>% distinct()

Заменить Stay.ID на местоположение

df.p2 <- merge(df.p2, Location.Stay.id.Recon, by="Stay.id") 

Средняя продолжительность пребывания в каждом местоположении

Avg.length <- df.p2 %>% 
  dplyr::group_by(Location.p1, Month) %>%
  dplyr::summarize(Mean = mean(Stay.length, na.rm=TRUE))

, что приводит к:

# A tibble: 3 x 3
# Groups:   Location.p1 [3]
  Location.p1 Month    Mean
  <chr>       <chr>   <dbl>
1 Loc.1       January   1.5
2 Loc.2       January   3  
3 Loc.3       January   2  

Ответы [ 2 ]

3 голосов
/ 04 октября 2019

Вот подход с dplyr и lubridate:

library(dplyr); library(lubridate)
df.p1 %>%
  mutate_if(is.factor, as.character) %>%
  # Above used b/c lag function below seems to have trouble with factors
  group_by(Character.p1, month = floor_date(ymd(V1), "month")) %>%
  mutate(new_stay = if_else(Location.p1 != lag(Location.p1, default = ""), 1, 0),
         stay_num = cumsum(new_stay)) %>%
  count(Character.p1, Location.p1, month, stay_num) %>%
  group_by(month, Location.p1) %>%
  summarise(Mean = mean(n))

#  month      Location.p1  Mean
#  <date>     <chr>       <dbl>
#1 2019-01-01 Loc.1         1.5
#2 2019-01-01 Loc.2         3  
#3 2019-01-01 Loc.3         2  
2 голосов
/ 04 октября 2019

Если я вас правильно понял, вам нужно что-то вроде

library(dplyr)

df %>%
  mutate(V1 = as.Date(V1), 
         month = format(V1, "%B")) %>%
  group_by(Location.p1, month, group = data.table::rleid(Location.p1))  %>%
  summarise(diff = as.integer(diff(range(V1)) + 1)) %>%
  summarise(mean = mean(diff))

#  Location.p1 month    mean
#  <fct>       <chr>   <dbl>
#1 Loc.1       January   1.5
#2 Loc.2       January   3  
#3 Loc.3       January   2  

data

df <- structure(list(V1 = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 1L, 
2L, 3L, 4L, 5L, 6L, 7L), .Label = c("2019-01-01", "2019-01-02", 
"2019-01-03", "2019-01-04", "2019-01-05", "2019-01-06", "2019-01-07"
), class = "factor"), Character.p1 = structure(c(2L, 2L, 2L, 
2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("Ellen", 
"Paul"), class = "factor"), Location.p1 = structure(c(1L, 1L, 
2L, 2L, 2L, 2L, 1L, 2L, 2L, 2L, 3L, 3L, 2L, 2L), .Label = c("Loc.1", 
"Loc.2", "Loc.3"), class = "factor")), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14"))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...