我有一个 data.table,想要做类似于 data[ !is.na(variable) ]
的操作。但是,对于完全缺失的组,我希望只保留该组的第一行。因此,我想使用 by 进行子集操作。我在网上做了一些研究,找到了一个解决方案,但我认为它效率低下。
下面提供了一个示例,展示了我希望实现的内容。我想知道是否可以在不创建两个额外列的情况下完成这个操作。
d_sample = data.table( ID = c(1, 1, 2, 2, 3, 3),
Time = c(10, 15, 100, 110, 200, 220),
Event = c(NA, NA, NA, 1, 1, NA))
d_sample[ !is.na(Event), isValidOutcomeRow := T, by = ID]
d_sample[ , isValidOutcomePatient := any(isValidOutcomeRow), by = ID]
d_sample[ is.na(isValidOutcomePatient), isValidOutcomeRow := c(T, rep(NA, .N - 1)), by = ID]
d_sample[ isValidOutcomeRow == T ]
编辑:这里是一些使用包含60K行数据的数据集进行速度比较的thelatemail和Frank的解决方案。
d_sample = data.table( ID = sort(rep(seq(1,30000), 2)),
Time = rep(c(10, 15, 100, 110, 200, 220), 10000),
Event = rep(c(NA, NA, NA, 1, 1, NA), 10000) )
在我的电脑上,thelatemail的解决方案运行时间为20.65
。
system.time(d_sample[, if(all(is.na(Event))) .SD[1] else .SD[!is.na(Event)][1], by=ID])
弗兰克的第一种解决方案运行时间为 0
system.time( unique( d_sample[order(is.na(Event))], by="ID" ) )
弗兰克的第二个解决方案运行时间为0.05
system.time( d_sample[order(is.na(Event)), .SD[1L], by=ID] )