Функция R для группировки данных и суммирования по временному интервалу в другом столбце - PullRequest
0 голосов
/ 06 января 2020

У меня есть данные в следующем формате:

enter image description here

Первый столбец - это идентификатор человека с его ИМТ, измеренным в разное время в Дата столбца. Я хочу взять среднее значение ИМТ за период в один год, то есть за 6 месяцев до и через 6 месяцев после Date_of_diagnosis. Обратите внимание, что датой диагностики является та же дата.

Ожидаемый результат примерно такой:

ID   Date         BMI    Date_of_diagnosis Avg BMI
718  07-01-1994   28.75  13-12-1999        25.8
718  07-01-1994   28.75  13-12-1999
718  07-01-1994   28.75   13-12-1999

1 Ответ

0 голосов
/ 06 января 2020

Итак, вот метод с использованием dplyr;

Обратите внимание, что в R есть множество функций, которые могут предоставлять месяцы между двумя датами в месяцах, однако в основном они предполагают 30-дневные месяцы, поэтому я предпочитаю строить пользовательская функция, но вы можете использовать любую функцию

Также здесь я сделал интервал меньше / больше равным друг другу, как указано, но вы можете изменить это, установив другую переменную.

library(dplyr)

# Sample of the input data
data <-
  data.frame(
    ID = c(718, 718, 718),
    Date = lubridate::dmy(c("07-01-1994", "07-01-1994", "07-01-1994")),
    BMI = c(28.75, 28.75, 28.75),
    Date_of_diagnosis = lubridate::dmy(c("13-12-1999", "13-12-1999", "13-12-1999"))
  )

# Function to calculate months between 2 dates in months
months_between <- function(end_date, start_date) {
  ed <- as.POSIXlt(end_date)
  sd <- as.POSIXlt(start_date)
  12 * (ed$year - sd$year) + (ed$mon - sd$mon)
}

# Setting the interval i.e. 72 months before/after diagnosis
num_months <- 72

data %>%
  # If the difference between diagnosis and date is less/more than Date by num_month
  # then consider the BMI
  mutate(avg_bmi = 
           ifelse(between(months_between(Date_of_diagnosis, Date), 0, num_months) |
                    between(months_between(Date_of_diagnosis, Date), -1 * num_months, 0), 
                  BMI, NA)) %>%
  group_by(ID) %>% # To calculate for each ID
  mutate(avg_bmi = mean(avg_bmi, na.rm = TRUE)) # Calculating average BMI for interval

# # A tibble: 3 x 5
# # Groups:   ID [1]
# ID Date         BMI Date_of_diagnosis avg_bmi
# <dbl> <date>     <dbl> <date>              <dbl>
# 718 1994-01-07  28.8 1999-12-13           28.8
# 718 1994-01-07  28.8 1999-12-13           28.8
# 718 1994-01-07  28.8 1999-12-13           28.8
...