2016-02-06 4 views
1

Я хотел бы рассчитать попарное среднее и среднее число дней между несколькими переменными даты.Расчет средней разницы между комбинациями дат

Мои исходные данные df может выглядеть следующим образом:

id  invitation account_date first_order second_order third_order 
1 1/1/2016  1/7/2016  1/20/2016  1/22/2016  NA 
2 1/1/2016  1/8/2016  1/22/2016  1/23/2016  1/25/2016 
3 1/1/2016  1/5/2016  1/20/2016  2/1/2016   NA 
4 1/1/2016  1/2/2016  1/18/2016  2/4/2016   2/6/2016 

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

id  inv_to_act act_to_first act_to_sec act_to_third 
1  6   13    2    NA 
2  7   14    1    2 
3  4   15    12   NA 
4  1   16    17   2 

А затем с помощью базового R: mean(df$act_to_first,na.rm=T).

Но я хотел бы вычислить эти вычисления на нескольких наборах данных или подмножествах одного и того же набора данных, поэтому он не масштабируется, чтобы делать каждый шаг снова и снова. Кроме того, я уверен, что должно быть решение melt или plyr, которое я не понял.

+1

Если у вас есть много наборов данных, вы можете разместить их в 'list' и использовать' lapply' – akrun

+0

@akrun мне на самом деле нужно, чтобы запустить это на подмножества данных, таким образом, 'plyr' похоже, было бы более идеальным. Руководство по 'lapply' также было бы высоко оценено :) – roody

+0

Если вам нужно запустить группу по условию, вы можете использовать' dplyr/data.table' – akrun

ответ

1

Вы могли бы вычислить разницу дат между каждой парой дат, пробегает по парам и с помощью difftime:

combos <- combn(tail(names(df), -1), 2) 
diffs <- apply(combos, 2, function(x) { 
    difftime(df[,x[2]], df[,x[1]], units="days") 
}) 
colnames(diffs) <- paste0(combos[1,], "_TO_", combos[2,]) 
diffs 
#  invitation_TO_account_date invitation_TO_first_order invitation_TO_second_order invitation_TO_third_order account_date_TO_first_order 
# [1,]       6      19       21      NA       13 
# [2,]       7      21       22      24       14 
# [3,]       4      19       31      NA       15 
# [4,]       1      17       34      36       16 
#  account_date_TO_second_order account_date_TO_third_order first_order_TO_second_order first_order_TO_third_order second_order_TO_third_order 
# [1,]       15       NA       2       NA       NA 
# [2,]       15       17       1       3       2 
# [3,]       27       NA       12       NA       NA 
# [4,]       33       35       17       19       2 

После выполнения этого шага, вы должны быть в состоянии легко вычислить среднее значение каждого столбца:

colMeans(diffs, na.rm=TRUE) 
# invitation_TO_account_date invitation_TO_first_order invitation_TO_second_order invitation_TO_third_order account_date_TO_first_order 
#       4.5       19.0       27.0       30.0       14.5 
# account_date_TO_second_order account_date_TO_third_order first_order_TO_second_order first_order_TO_third_order second_order_TO_third_order 
#       22.5       26.0       8.0       11.0       2.0 

После того, как у вас есть эти функции, вы можете поместить их в функции и применить эту функцию к любому входу df:

meanDateRanges <- function(df) { 
    combos <- combn(tail(names(df), -1), 2) 
    diffs <- apply(combos, 2, function(x) { 
    difftime(df[,x[2]], df[,x[1]], units="days") 
    }) 
    colnames(diffs) <- paste0(combos[1,], "_TO_", combos[2,]) 
    colMeans(diffs, na.rm=TRUE) 
} 

Вы можете запустить эту функцию на фрейме входных данных с meanDateRanges(df) или по их списку lapply(df.list, meanDateRanges).

данных:

df <- structure(list(id = 1:4, invitation = structure(list(sec = c(0, 
0, 0, 0), min = c(0L, 0L, 0L, 0L), hour = c(0L, 0L, 0L, 0L), 
    mday = c(1L, 1L, 1L, 1L), mon = c(0L, 0L, 0L, 0L), year = c(116L, 
    116L, 116L, 116L), wday = c(5L, 5L, 5L, 5L), yday = c(0L, 
    0L, 0L, 0L), isdst = c(0L, 0L, 0L, 0L), zone = c("EST", "EST", 
    "EST", "EST"), gmtoff = c(NA_integer_, NA_integer_, NA_integer_, 
    NA_integer_)), .Names = c("sec", "min", "hour", "mday", "mon", 
"year", "wday", "yday", "isdst", "zone", "gmtoff"), class = c("POSIXlt", 
"POSIXt")), account_date = structure(list(sec = c(0, 0, 0, 0), 
    min = c(0L, 0L, 0L, 0L), hour = c(0L, 0L, 0L, 0L), mday = c(7L, 
    8L, 5L, 2L), mon = c(0L, 0L, 0L, 0L), year = c(116L, 116L, 
    116L, 116L), wday = c(4L, 5L, 2L, 6L), yday = c(6L, 7L, 4L, 
    1L), isdst = c(0L, 0L, 0L, 0L), zone = c("EST", "EST", "EST", 
    "EST"), gmtoff = c(NA_integer_, NA_integer_, NA_integer_, 
    NA_integer_)), .Names = c("sec", "min", "hour", "mday", "mon", 
"year", "wday", "yday", "isdst", "zone", "gmtoff"), class = c("POSIXlt", 
"POSIXt")), first_order = structure(list(sec = c(0, 0, 0, 0), 
    min = c(0L, 0L, 0L, 0L), hour = c(0L, 0L, 0L, 0L), mday = c(20L, 
    22L, 20L, 18L), mon = c(0L, 0L, 0L, 0L), year = c(116L, 116L, 
    116L, 116L), wday = c(3L, 5L, 3L, 1L), yday = c(19L, 21L, 
    19L, 17L), isdst = c(0L, 0L, 0L, 0L), zone = c("EST", "EST", 
    "EST", "EST"), gmtoff = c(NA_integer_, NA_integer_, NA_integer_, 
    NA_integer_)), .Names = c("sec", "min", "hour", "mday", "mon", 
"year", "wday", "yday", "isdst", "zone", "gmtoff"), class = c("POSIXlt", 
"POSIXt")), second_order = structure(list(sec = c(0, 0, 0, 0), 
    min = c(0L, 0L, 0L, 0L), hour = c(0L, 0L, 0L, 0L), mday = c(22L, 
    23L, 1L, 4L), mon = c(0L, 0L, 1L, 1L), year = c(116L, 116L, 
    116L, 116L), wday = c(5L, 6L, 1L, 4L), yday = c(21L, 22L, 
    31L, 34L), isdst = c(0L, 0L, 0L, 0L), zone = c("EST", "EST", 
    "EST", "EST"), gmtoff = c(NA_integer_, NA_integer_, NA_integer_, 
    NA_integer_)), .Names = c("sec", "min", "hour", "mday", "mon", 
"year", "wday", "yday", "isdst", "zone", "gmtoff"), class = c("POSIXlt", 
"POSIXt")), third_order = structure(list(sec = c(NA, 0, NA, 0 
), min = c(NA, 0L, NA, 0L), hour = c(NA, 0L, NA, 0L), mday = c(NA, 
25L, NA, 6L), mon = c(NA, 0L, NA, 1L), year = c(NA, 116L, NA, 
116L), wday = c(NA, 1L, NA, 6L), yday = c(NA, 24L, NA, 36L), 
    isdst = c(-1L, 0L, -1L, 0L), zone = c("", "EST", "", "EST" 
    ), gmtoff = c(NA_integer_, NA_integer_, NA_integer_, NA_integer_ 
    )), .Names = c("sec", "min", "hour", "mday", "mon", "year", 
"wday", "yday", "isdst", "zone", "gmtoff"), class = c("POSIXlt", 
"POSIXt"))), .Names = c("id", "invitation", "account_date", "first_order", 
"second_order", "third_order"), row.names = c(NA, -4L), class = "data.frame") 
Смежные вопросы