使用 .SD 在 data.table 中获得条件最大值
Getting a conditional maximum in data.table using .SD
我已经尝试了一段时间了,但事实证明这很困难,所以我不得不寻求您的宝贵帮助。
我的问题是我有一个包含三个主要阵营的向量:ID、date 和 state。由于多个寄存器,ID 在数据库中重复多次。 日期 就是注册完成的日期。 状态可能是'active'或'inactive'。
我需要做以下事情:对于每个文档,我必须只取最近的一个,优先级如下:如果有一个 'Active' 寄存器,我必须取所有可能的最近的 'Active'个,如果没有active我一般都取最近的那个。
例如,假设我有这个
data.table(ID=rep(seq(1,3),each=3),state=c("active","active","active","inactive","inactive","inactive","active","active","inactive"),Date=as.Date(c("2016-01-01","2016-01-03","2016-01-02","2016-01-04","2016-01-05","2016-01-06","2016-01-07","2016-01-08","2016-01-10")),value=seq(1,9))
ID state Date value
1: 1 active 2016-01-01 1
2: 1 active 2016-01-03 2
3: 1 active 2016-01-02 3
4: 2 inactive 2016-01-04 4
5: 2 inactive 2016-01-05 5
6: 2 inactive 2016-01-06 6
7: 3 active 2016-01-07 7
8: 3 active 2016-01-08 8
9: 3 inactive 2016-01-10 9
我一直在尝试进行类似于以下的操作:
dx[,list(if (length(.SD[state=="active"])==0)
{.SD[which.max(Date)]}
else {.SD[state=="active"]
[which.max(Date)]})
,by='ID']
所以我得到类似的东西:
ID state Date value
1: 1 active 2016-01-03 2
2: 2 inactive 2016-01-06 6
3: 3 active 2016-01-08 8
我想用 data.table 进行向量化运算。如果你能帮助我,那就太棒了!
谢谢,
奥尔多
我们可以使用对 OP 代码的修改来获得预期的输出。按'ID'、if
分组,'state'中有any
'active'个字符串,我们得到最大'Date'的索引,其中'state' 是 'active'(使用 which.max
)和子集 Data.table(.SD[which.max...
)或 else
我们得到最大的 'Date' 索引(which.max(Date)
) 然后使用 .SD
.
dx[,if(any(state=='active')) .SD[which.max(Date[state=='active'])]
else .SD[which.max(Date)], ID]
# ID state Date value
#1: 1 active 2016-01-03 2
#2: 2 inactive 2016-01-06 6
#3: 3 active 2016-01-08 8
或者另一种选择是 order
'Date' 和 'state' 列和 select 'ID'
的第一次观察
dx[order(ID,state, -Date),.SD[1L], ID]
# ID state Date value
#1: 1 active 2016-01-03 2
#2: 2 inactive 2016-01-06 6
#3: 3 active 2016-01-08 8
我已经尝试了一段时间了,但事实证明这很困难,所以我不得不寻求您的宝贵帮助。
我的问题是我有一个包含三个主要阵营的向量:ID、date 和 state。由于多个寄存器,ID 在数据库中重复多次。 日期 就是注册完成的日期。 状态可能是'active'或'inactive'。
我需要做以下事情:对于每个文档,我必须只取最近的一个,优先级如下:如果有一个 'Active' 寄存器,我必须取所有可能的最近的 'Active'个,如果没有active我一般都取最近的那个。
例如,假设我有这个
data.table(ID=rep(seq(1,3),each=3),state=c("active","active","active","inactive","inactive","inactive","active","active","inactive"),Date=as.Date(c("2016-01-01","2016-01-03","2016-01-02","2016-01-04","2016-01-05","2016-01-06","2016-01-07","2016-01-08","2016-01-10")),value=seq(1,9))
ID state Date value
1: 1 active 2016-01-01 1
2: 1 active 2016-01-03 2
3: 1 active 2016-01-02 3
4: 2 inactive 2016-01-04 4
5: 2 inactive 2016-01-05 5
6: 2 inactive 2016-01-06 6
7: 3 active 2016-01-07 7
8: 3 active 2016-01-08 8
9: 3 inactive 2016-01-10 9
我一直在尝试进行类似于以下的操作:
dx[,list(if (length(.SD[state=="active"])==0)
{.SD[which.max(Date)]}
else {.SD[state=="active"]
[which.max(Date)]})
,by='ID']
所以我得到类似的东西:
ID state Date value
1: 1 active 2016-01-03 2
2: 2 inactive 2016-01-06 6
3: 3 active 2016-01-08 8
我想用 data.table 进行向量化运算。如果你能帮助我,那就太棒了!
谢谢, 奥尔多
我们可以使用对 OP 代码的修改来获得预期的输出。按'ID'、if
分组,'state'中有any
'active'个字符串,我们得到最大'Date'的索引,其中'state' 是 'active'(使用 which.max
)和子集 Data.table(.SD[which.max...
)或 else
我们得到最大的 'Date' 索引(which.max(Date)
) 然后使用 .SD
.
dx[,if(any(state=='active')) .SD[which.max(Date[state=='active'])]
else .SD[which.max(Date)], ID]
# ID state Date value
#1: 1 active 2016-01-03 2
#2: 2 inactive 2016-01-06 6
#3: 3 active 2016-01-08 8
或者另一种选择是 order
'Date' 和 'state' 列和 select 'ID'
dx[order(ID,state, -Date),.SD[1L], ID]
# ID state Date value
#1: 1 active 2016-01-03 2
#2: 2 inactive 2016-01-06 6
#3: 3 active 2016-01-08 8