Подсчет вхождений факторной переменной между двумя датами posixCT - PullRequest
0 голосов
/ 26 февраля 2019

У меня есть большой фрейм данных, в котором каждая строка представляет отдельный случай события.В качестве иллюстрации рассмотрим фрейм данных, который содержит следующие пять столбцов:

  1. дата и время инцидента
  2. дата и время инцидента + 2 часа
  3. дата и время происшествия - 2 часа
  4. город происшествия
  5. тип происшествия

Ниже приведен воспроизводимый пример.

library(dplyr)
library(lubridate)
set.seed(5567)

df <- data.frame(time = sample(seq(as.POSIXct('2019/01/10'), 
                                   as.POSIXct('2019/01/20'), 
                                   by="15 mins"), 100))

df <- mutate(df,
             two.Before = df$time - hours(2),
             two.After = df$time + hours(2),
             loc = sample(c("New York", "Boston", "Atlanta", "Chicago"), 100, 
                          replace=TRUE) %>% as.factor,
             type = sample(c("Bus", "Car"), 100, 
                           replace=TRUE) %>% as.factor)

head(df)

Для каждого экземпляра мне нужно создать два новых столбца:

  1. столбец, в котором указано количество экземпляров, которые произошли в этом том же городе. в течение двух часов до и двух часов после инцидента.
  2. аналогичный столбец, в котором содержится число случаев, произошедших в этом том же городе , которые были автобусные инциденты и только автобусные инциденты, в течение двух часов до и двух часов после инцидента.

Если кто-то может помочь с этим, это было бы очень признательно.Мои даты все posixCt и категории все факторы.Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 26 февраля 2019

Обычно неоптимальной идеей является использование циклов в r, так как любой умеренный набор данных будет действительно завален.Причина этого указана в других ответах на переполнение стека, если вы заинтересованы.Лучшая практика в r: если вы думаете об использовании цикла for для просмотра всех записей во фрейме данных, используйте вместо этого apply family функций.

Я написал небольшой код нижекоторый должен выполнить задачу довольно быстро и основывается на коде, который вы предоставили.

df$row <- rownames(df)

#Column 1: count occurrences +/- 2hrs within same city
df$col1 <- mapply(function(time, city, row) sum(df[df$row != row,"two.Before"] <= time & df[df$row != row,"two.After"] >= time & df[df$row != row,"loc"] == city), 
              df$time, df$loc, df$row)

#Column2: count occurrences +/- 2hrs within same city and on a bus
df$col2 <- mapply(function(time, city, bus, row) sum(df[df$row != row,"two.Before"] <= time & df[df$row != row,"two.After"] >= time & df[df$row != row,"loc"] == city & df[df$row != row,"type"] == "Bus"), 
              df$time, df$loc, df$type, df$row)

#Remove row index
df <- subset(df, select = -c(row))

Дайте мне знать, если у вас есть какие-либо вопросы.Кажется, он работает так, как задумано для нескольких точек данных, которые я тестировалЭто предполагает, что вы не хотите считать эту строку в ваших двух подсчетах, иначе все подсчеты col1 будут равны 1.

Редактировать

Код для просмотра только за два часа до инцидента, приведенного ниже (снова опирается на предоставленный код).

df$row <- as.numeric(rownames(df))

#Column 1: count occurrences +/- 2hrs within same city
df$col1 <- mapply(function(time, city, row) sum(df[df$row != row,"time"] <= time & df[df$row != row,"two.After"] >= time & df[df$row != row,"loc"] == city), 
              df$time, df$loc, df$row)

#Column2: count occurrences +/- 2hrs within same city and on a bus
df$col2 <- mapply(function(time, city, bus, row) sum(df[df$row != row,"time"] <= time & df[df$row != row,"two.After"] >= time & df[df$row != row,"loc"] == city & df[df$row != row,"type"] == "Bus"), 
              df$time, df$loc, df$type, df$row)
0 голосов
/ 26 февраля 2019

Мой способ сделать это с помощью петель.Время выполнения довольно высокое, но работает точно.Во-первых, это col1, который учитывается в течение + -2 часов в том же городе.Примечание: последняя строка в цикле делает -1, чтобы исключить двойной счет первого наблюдения.Второй - col2, который делает то же самое, что и выше, но также включает type = "Bus".Примечание: последняя строка в цикле делает -1 это, чтобы исключить двойной подсчет первого наблюдения (немного отличается от 1-го цикла, потому что нам нужно убедиться, что в первую очередь существует более 1 наблюдения, потому что не все типы"Автобус").

df$col1<-0
for (i in 1:nrow(df)){
  for (j in 1:nrow(df)){
    if (hour(df[i,]$time)==hour(df[j,]$time) & df[i,]$loc==df[j,]$loc) 
      {df[i,]$col1<-df[i,]$col1+1}
    else if ((hour(df[i,]$time)-hour(df[j,]$time))<2 & (hour(df[i,]$time)-hour(df[j,]$time))>(-2) & df[i,]$loc==df[j,]$loc)
      {df[i,]$col1<-df[i,]$col1+1}
  }
  df[i,]$col1<-df[i,]$col1-1
}


df$col2<-0
for (i in 1:nrow(df)){
  for (j in 1:nrow(df)){
    if (hour(df[i,]$time)==hour(df[j,]$time) & df[i,]$loc==df[j,]$loc & df[j,]$type=="Bus")
      {df[i,]$col2<-df[i,]$col2+1}
    else if ((hour(df[i,]$time)-hour(df[j,]$time))<2 & (hour(df[i,]$time)-hour(df[j,]$time))>(-2) & 
             df[i,]$loc==df[j,]$loc & df[j,]$type=="Bus")
      {df[i,]$col2<-df[i,]$col2+1}
  }
  if (df[i,]$col2>0){df[i,]$col2<-df[i,]$col2-1}
}

Вы можете набрать head(df), чтобы посмотреть результаты или просто просмотреть весь набор данных.

Пожалуйста, дайте мне знать, если у вас есть какие-либо вопросы олюбая часть кода.

...