Векторизация цикла for для расчетов между двумя наборами данных в R - PullRequest
0 голосов
/ 07 мая 2018

У меня есть набор данных A с местом, датой начала и датой окончания. С другой стороны, у меня есть набор данных B также с указанием места, даты и количества автомобилей.

library(data.table)
A <- data.table(Place = c(rep(c("Place_1","Place_2"), each = 20)),
          Start_date = as.Date("2010-01-15"),
          Finish_date = as.Date(rep(c("2011-03-01","2012-04-30","2012-01-20","2011-04-05"), each = 10)))


set.seed(1001)
B <- data.table(Date = rep(seq.Date(from = as.Date("2010-01-01"), to = as.Date("2013-01-01"), by="day"), 2),
          Place = rep(c("Place_1","Place_2"),each = 1097),
          Cars = round(runif(2194, 0, 10), 0))    

Мне нужно вычислить в наборе данных A новый столбец (общее количество автомобилей), которое представляет собой сумму автомобилей в наборе данных B; эта сумма автомобилей должна быть для определенного места и в течение определенного периода времени.

Это легко сделать с помощью оператора for-loop.

for (i in 1:nrow(A)) {
    A$Tcars[i] <- sum(B[Place == A$Place[i] & Date > A$Start_date[i] & Date < A$Finish_date[i]]$Cars)
}

Но мой реальный набор данных имеет 30 000 строк, и опция цикла неэффективна и требует много времени. Итак, я ищу векторизованный способ сделать это. Я пробовал следующий код, но он не работает:

A$Tcars<-sum(B[Place == A$Place & Date > A$Start_date & Date < A$Finish_date]$Cars)

1 Ответ

0 голосов
/ 08 мая 2018

Вы можете использовать неэквивалентное объединение для обновления таблицы:

library(data.table)

A[, n := B[.SD, on=.(Place, Date > Start_date, Date < Finish_date), 
  sum(Cars), by=.EACHI]$V1]

Если вы посмотрите на ?data.table и другие вводные материалы, перечисленные при первом наборе library(data.table), вы получите некоторую интуицию для :=, on=, by= и т. Д.

...