Рулон с использованием дат не допускается? - PullRequest
0 голосов
/ 13 сентября 2018

Для создания таблицы мне нужно сопоставить посещения людей в одном месте (скажем, в церкви) с посещениями в другом (скажем, магазине).В этом упрощенном примере мне нужно найти первый раз, когда люди ходили в церковь, и последний раз перед каждым посещением церкви они ходили в магазин.Итак, учитывая

> test_church=data.table(subject=as.factor(c('S_01','S_01','S_02','S_02')),
    date=as.Date(c('2018-01-15','2018-01-29','2018-01-08','2018-01-22')),
    key='subject')

> test_shop=data.table(subject=as.factor(c('S_01','S_02','S_01','S_02',
                                         'S_01','S_02','S_01','S_02')),
                     date=as.Date(c('2018-01-03','2018-01-7',
                                    '2018-01-11','2018-01-14',
                                    '2018-01-17','2018-01-20',
                                    '2018-01-23','2018-01-26')),
                     key='subject')

> str(test_church)
Classes ‘data.table’ and 'data.frame':  4 obs. of  2 variables:
 $ subject: Factor w/ 2 levels "S_01","S_02": 1 1 2 2
 $ date   : Date, format: "2018-01-15" "2018-01-29" ...
 - attr(*, "sorted")= chr "subject"
 - attr(*, ".internal.selfref")=<externalptr> 
> str(test_shop)
 Classes ‘data.table’ and 'data.frame': 8 obs. of  2 variables:
 $ subject: Factor w/ 2 levels "S_01","S_02": 1 1 1 1 2 2 2 2
 $ date   : Date, format: "2018-01-03" "2018-01-11" ...
 - attr(*, "sorted")= chr  "subject" "date"
 - attr(*, ".internal.selfref")=<externalptr> 

посещения церкви, которые я ищу, составляют "2018-01-15" для S_01 и "2018-01-08" для S_02 и соответствующие последние посещения магазина перед тем, как "2018-01-11" для S_01 (последний перед "2018-01-15") и "2018-01-07" для S_02 (последний перед "2018-01-08").

Мои реальные таблицы намного больше (поэтому я хочу использовать функции data.table), носоответствующие столбцы subject и date.

Первое посещение церкви по предмету, которое я нахожу с

first_church = test_church[ J(unique(subject)), on = 'subject', mult = 'first' ]

, но затем, когда я хочу найти соответствующее посещение магазина с

church_shop = test_shop[ first_church, on='date', roll=T ]

Я получаю

> church_shop
   subject       date i.subject
1:    S_02 2018-01-15      S_01
2:    S_02 2018-01-08      S_02

Таким образом, вместо того, чтобы находить даты для правильных посещений, я получаю список предметов в моей новой таблице, который даже не является правильным!(S_02 ничего не делает на "2018-01-15").То же самое происходит, если я установил ключи first_church и test_shop на c('subject','date').

Есть ли способ сделать это с помощью объединений, или мне просто написать цикл for?

1 Ответ

0 голосов
/ 14 сентября 2018

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

#get first church visit
setorder(test_church, subject, date)
first_church <- test_church[test_church[, .I[1L], by=.(subject)]$V1]

#rolling join with Frank's fix
test_shop[first_church, .(x.subject, x.date), on=c("subject", "date"), roll=TRUE]

вывод:

   x.subject     x.date
1:      S_01 2018-01-11
2:      S_02 2018-01-07
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...