Я пытаюсь вычислить некоторые исторические c средние значения для достаточно большого фрейма данных (размер 50 000rx 150 c), и для этого мне сначала нужно подгруппировать данные в соответствии с двумя критериями, а затем применить некоторую арифметику c функция для одного из подмножеств столбцов. Затем я записываю результат в другой фрейм данных в виде нового столбца подсчетов / средних / взвешенных средних за определенные периоды. Из-за размера наборов данных (и ограничений моего навыка кодирования) это занимает много времени, и мой вопрос: есть ли лучший способ решения этой проблемы в R?
Вот простой пример, чтобы проиллюстрировать, что я пытаюсь сделать:
library(lubridate)
### Create dataframe Df
date <- c("01/01/2020", "02/01/2020", "02/01/2020","02/01/2020", "03/01/2020",
"03/01/2020", "03/01/2020", "03/01/2020", "04/01/2020", "04/01/2020")
date <- dmy(date)
name <- c("john", "paul", "john", "peter", "peter",
"john", "andrew", "john", "peter", "peter")
visits <- c(1, 3, 2, 1, 3,
4, 6, 1 ,1, 9)
Df <- data.frame(date, name, visits)
Df
### Create dataframe Df1
date1 <- c("01/01/2020", "02/01/2020", "03/01/2020", "04/01/2020")
date1 <- dmy(date1)
name1 <- c("john", "paul", "andrew", "peter")
totvisits <- c(0, 0, 0, 0)
Df1 <- data.frame(date1, name1, totvisits)
Df1
Df$name <- as.character(Df$name)
Df1$name1 <- as.character(Df1$name1)
В этом примере я хочу (для каждой пары имя строки1 / дата1 в Df1) подставить Df в соответствии с датой / именем и вернуть количество посещений каждое «имя1» указывалось перед каждым значением «дата1» ie путем суммирования столбца «посещения» для даты <дата1. Затем я хочу сохранить это значение в соответствующей строке нового столбца (в этом примере «Df1 $ totvisits»). Насколько я могу судить, для этого требуется какой-то l oop, что в больших наборах данных неуклюже и занимает много времени. Я тоже попробовал mapply (), но это не так быстро, и это не ускользает от того факта, что мое решение не очень элегантно. </p>
### loop
for (i in 1:dim(Df1)[1]) {
Df1[i, 3] <- sum(subset(Df, Df$name == Df1$name1[i] & Df$date <= Df1$date1[i])[,3])
}
Df1
### apply()
f <- function(x, y) {
sum(subset(Df, (Df$name == x) & (Df$date <= y))[,3])
}
Df1[, 3] <- mapply(f, x = Df1$name1, y = Df1$date1)
Df1
Любая идея или указатели относительно альтернативного подхода были бы намного признателен.
РЕДАКТИРОВАТЬ:
Чтобы прояснить вышесказанное, я пытаюсь добавить новый столбец в Df1 ('Df1 $ totvisits'), где каждая запись является результатом поиска date1 / name1 в другом фрейме данных ('Df) и возврата суммы посещений, которые произошли до' date1 'для каждого' name1 '. Например, в строке «2020-01-02 paul» в Df1 мне нужно получить значения посещений из Df, где «name == paul» и «date <= 02/01/2020», а затем поместить сумму из них в третьем столбце, второй ряд Df1. Поскольку в Df1 есть только один экземпляр paul с датой <= "2020-01-02", эта запись становится = 3. </p>
Я хотел бы иметь возможность расширить это до поиска значения из диапазона дат, например, даты между x и y, когда человек z посетил. Я хотел бы сделать это, чтобы я мог рассчитывать посещения в n-дневном окне.
В контексте dplyr, я думаю, что я пытаюсь сделать, это 'mutate' Df1 с новым столбцом, который содержит выражение, которое возвращает значения сумм Df $ посещений до (/ между) каждой даты. Просто я не могу заставить его работать, и это сводит меня с ума.
Заранее спасибо за любую помощь с этим.