r - 按组的多个第一个和最后一个非 NA 值
问题描述
我有以下数据表:
require(data.table)
dt = data.table(
id = c(rep('Grp 1', 31), rep('Grp 2', 31)),
date = rep(as.IDate(as.IDate('2020-01-01') : as.IDate('2020-01-31')), 2),
change = c(rep(NA, 5), rep('yes', 5), rep(NA, 10), rep('yes', 3), rep(NA, 8),
rep(NA, 2), rep('yes', 8), rep(NA, 8), rep('yes', 5), rep(NA, 8))
)
对于每个组id
,我想过滤一个系列的第一个和最后一个,它date
由第二列定义(即非 NA)。我可以执行以下操作,这将按组为我提供第一个和最后一个非 NA 行。然而,问题是该系列每组出现不止一次。change
yes
dt[ !is.na(change),
.(head(date, 1),
tail(date, 1)),
.(id) ]
这些是我想要过滤的行索引:
dt[c(6,10,21,23,34,41,50,54)]
解决方案
id
一种方法是为由andchange
组合标识的每个条纹赋予唯一的组 ID 。我们可以使用rleid
来生成这样的游程类型 ID。考虑这样的事情
dt[,
gid := rleid(id, change)
][!is.na(change),
as.list(range(date)),
by = .(id, gid)
][,
gid := NULL
]
请注意,我还假设您想要日期范围,而不是真正的第一个和最后一个元素。如果日期不按时间顺序排列,您的方法将失败。输出看起来像这样
id V1 V2
1: Grp 1 2020-01-06 2020-01-10
2: Grp 1 2020-01-21 2020-01-23
3: Grp 2 2020-01-03 2020-01-10
4: Grp 2 2020-01-19 2020-01-23
rleid
像这样工作
> rleid(c(1, 1, 2, 3, 3), c("a", "b", "b", "d", "d"))
[1] 1 2 3 4 4
推荐阅读
- java - Java Swing:如何根据文本更改 JTable 列中非常单元格的颜色?
- python - 对于每个 ID ,查看是否有符合条件的行并创建一个新列
- swift - firebase 图像大小增加
- python - 在使用 python-flask 时,即使将我的 environemnt 设置为开发模式,它也会在我的 Anaconda 命令提示符中显示 Environmeent:production
- regex - 正则表达式:两个通配符的异或?
- c++ - std::vector 只保存最后一个被推送的元素
- python - 如何在不杀死当前进程的情况下杀死窗口中的进程
- mongodb - Mongoose Model.deleteMany() 仅删除匹配项的第一个元素
- linux - 关于可解析输出的家伙
- css - 单选按钮内的居中标签