R-tapply не сохраняет даты в формате

Мне нужно сделать быструю агрегацию по id_client дат: min, max, разница дат в месяцах и количество месяцев.

Пример таблицы:

tbl<-data.frame(id_cliente=c(1,1,1,1,2,3,3,3), 
fecha=c('2013-01-01', '2013-06-01','2013-05-01', '2013-04-01', '2013-01-01', '2013-01-01','2013-05-01','2013-04-01'))

Даты формата:

tbl$fecha<-as.Date(as.character(tbl$fecha))

Мой первый подход был ddply:

tbl2<-ddply(tbl, .(id_cliente), summarize, cant=length(id_cliente), 
max=max(fecha), min=min(fecha),
dif=length(seq(from=min, to=max, by='month')))

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

tbl3<-data.frame(cbind(dif=tapply(tbl$fecha, list(tbl$id_cliente), secuencia),
        hay=tapply(tbl$fecha, list(tbl$id_cliente), length),
        min=tapply(tbl$fecha, list(tbl$id_cliente), min),
        max=tapply(tbl$fecha, list(tbl$id_cliente), max)
        ))

В результате:

> tbl3
  dif hay   min   max
   6   4 15706 15857
   1   1 15706 15706
   5   3 15706 15826

В данном случае я получил вместо дат числа. Итак, поскольку следующее работает, я попытался использовать as.Date внутри tapply:

as.Date(15706, origin='1970-01-01')

MIN<-function(x){as.Date(min(x), origin='1970-01-01')}

Функция работает, но с tapply нет.

tbl3<-data.frame(cbind(min=tapply(tbl$fecha, list(tbl$id_cliente), MIN)))

И я все еще получил номер вместо даты. Как я могу это решить? Спасибо.


person GabyLP    schedule 06.12.2015    source источник


Ответы (2)


С помощью base R класс ?Date преобразуется в количество дней с 1 января 1970 года. Попробуйте использовать dplyr или data.table, чтобы сохранить класс даты:

дплир

library(dplyr)
tbl %>% group_by(id_cliente) %>%
        summarise(dif=length(seq(min(fecha), max(fecha), by='month')),
                  hay=length(fecha),
                  min=min(fecha),
                  max=max(fecha))
# Source: local data frame [3 x 5]
# 
#   id_cliente dif hay        min        max
# 1          1   6   4 2013-01-01 2013-06-01
# 2          2   1   1 2013-01-01 2013-01-01
# 3          3   5   3 2013-01-01 2013-05-01

data.table

library(data.table)
setDT(tbl)[,.(dif=length(seq(min(fecha), max(fecha), by='month')),
              hay= .N,
              min=min(fecha),
              max=max(fecha)), by=id_cliente]
#    id_cliente dif hay        min        max
# 1:          1   6   4 2013-01-01 2013-06-01
# 2:          2   1   1 2013-01-01 2013-01-01
# 3:          3   5   3 2013-01-01 2013-05-01
person Pierre L    schedule 06.12.2015

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

Интересно, что tapply возвращает правильные результаты, когда вы сохраняете столбец даты в текстовом формате, а затем вы можете преобразовать его в дату после:

tbl<-data.frame(id_cliente=c(1,1,1,1,2,3,3,3), 
                fecha=c('2013-01-01', '2013-06-01','2013-05-01', '2013-04-01', '2013-01-01', '2013-01-01','2013-05-01','2013-04-01'))
tbl3<-data.frame(cbind(dif=tapply(tbl$fecha, list(tbl$id_cliente), seq),
                        hay=tapply(tbl$fecha, list(tbl$id_cliente), length),
                        min=tapply(tbl$fecha, list(tbl$id_cliente), min),
                        max=tapply(tbl$fecha, list(tbl$id_cliente), max))) 
head(tbl3)
#         dif hay        min        max
# 1, 2, 3, 4   4 2013-01-01 2013-06-01
#          1   1 2013-01-01 2013-01-01
#    1, 2, 3   3 2013-01-01 2013-05-01
person B. Stanley    schedule 08.07.2020