TL; DR
ifelse
- это то, где что-то происходит. Положения Да и Нет должны быть одного класса.
Мое решение:
Сначала сгруппируйте по обоим столбцам
> DT[,max(col2),by=list(ID,col1)]
ID col1 V1
1: 1 Y 2004-01-01
2: 1 N <NA>
3: 2 Y 2003-01-01
4: 2 N 2005-01-01
5: 3 Y <NA>
6: 2 Y 2007-01-01
7: 3 N 2008-01-01
Затем просто возьмите Y.
> DT[,max(col2),by=list(ID,col1)][col1=='Y']
ID col1 V1
1: 1 Y 2004-01-01
2: 2 Y 2003-01-01
3: 3 Y <NA>
Теперь удалите ненужный второй столбец (или присвойте ему
> DT[,max(col2),by=list(ID,col1)][col1=='Y'][ , .(ID,V1)]
ID V1
1: 1 2004-01-01
2: 2 2003-01-01
3: 3 <NA>
Также можно объединить второй и третий этапы:
DT[,max(col2),by=list(ID,col1)][col1=='Y', .(ID,max_date=V1)]
Обновление : Когда я экспериментировал с ifelse
, я обнаружил, что здесь происходит ваше преобразование
k=as.Date('2001-01-01')
> k
[1] "2001-01-01"
> as.integer(k)
[1] 11323
> max(k,NA)
[1] NA
> min(k,NA)
[1] NA
> ifelse(Y=='N',k,NA)
Error in ifelse(Y == "N", k, NA) : object 'Y' not found
> Y='N'
> ifelse(Y=='N',k,NA)
[1] 11323
Обновление 2
Если вы попытаетесьвыполнив версию таблицы быстрых данных ifelse
, вы увидите, в чем проблема. Приведение происходит в обычном ifelse
, поскольку предложения «Да» и «Нет» не относятся к одному классу, и R должен принятьвремя для их произнесения, что также дает вам хит производительности. Помните: ifelse
должен быть векторизуемым . Для этого предложения Yes
и No
_ должны быть того же класса.
# the double colon is not really necessary. I'm just
# doing it to emphasize the provenance of `fifelse`
> data.table::fifelse(Y=='N',k,23)
Error in data.table::fifelse(Y == "N", k, 23) :
'yes' has different class than 'no'. Please make sure that both arguments have the same class.