r - R 数据帧 + 逻辑运算
问题描述
我有以下咨询。假设我有以下包含两列的基础,一列带有 ID,一列带有值。
我需要使用以下逻辑创建一个附加列(value_ok):对于每个具有相同字母的 ID,没有较高值的 ID 的数量应该大于较低值的 ID。如果发生这种情况,则应将其替换为相同的值。
db<-data.frame(id=c("A_1","A_2","A_3","A_4","B_1","B_2","B_3","B_4","C_1","C_2","C_3","C_4","D_1","D_2","D_3","D_4","E_1","E_4"),
value=c(10,9,8,7,7,8,9,5,15,30,14,20,10,10,10,20,30,40),
value_ok=c(10,9,8,7,9,9,9,5,30,30,20,20,20,20,20,20,40,40))
这是值和最终所需输出的示例。
id value value_ok
1 A_1 10 10
2 A_2 9 9
3 A_3 8 8
4 A_4 7 7
5 B_1 7 9
6 B_2 8 9
7 B_3 9 9
8 B_4 5 5
9 C_1 15 30
10 C_2 30 30
11 C_3 14 20
12 C_4 20 20
13 D_1 10 20
14 D_2 10 20
15 D_3 10 20
16 D_4 20 20
17 E_1 30 40
18 E_4 40 40
有人可以帮我完成这项任务吗?
谢谢!
解决方案
你可以做...
library(data.table)
setDT(db)
db[.N:1, v := cummax(value), by=sub("^(.+)_(.+)$", "\\1", id)]
id value value_ok v
1: A_1 10 10 10
2: A_2 9 9 9
3: A_3 8 8 8
4: A_4 7 7 7
5: B_1 7 9 9
6: B_2 8 9 9
7: B_3 9 9 9
8: B_4 5 5 5
9: C_1 15 30 30
10: C_2 30 30 30
11: C_3 14 20 20
12: C_4 20 20 20
13: D_1 10 20 20
14: D_2 10 20 20
15: D_3 10 20 20
16: D_4 20 20 20
17: E_1 30 40 40
18: E_4 40 40 40
.N:1
临时将表格从最后到第一个排序。by=
对行进行分组。v := cummax(value)
用每组内的累积最大值创建一个新列。
之后的非常难看的表达式by=
是由于在字符串中嵌入了重要信息(字母)。我建议永远不要这样做。如果你想转换成更好的东西,这里是一个参考:Split comma-separated strings in a column into separate rows
推荐阅读
- c++ - 如何避免`std::to_string()`将一个非常小的双数变为0?
- ios - UIButton 属性观察者 didset 从未调用过
- python - 致命错误:cuda_runtime_api.h:尝试在 docker 中使用 cuda 时没有这样的文件或目录
- html - 如何增加箭头进度条 CSS 的高度
- java - Java反应器如何正确启动异步可取消的副作用
- html - 将 'order' 与 flexbox 'row-reverse' 结合以实现所需的动态布局
- python - numpy 是否重用了未使用数组中的内存?
- c# - 将 C# 类属性作为参数传递给方法
- kubernetes - 运行主集群 kubernetes 后系统挂起
- c - O(log n) 是正确的运行时间 T(n) 吗?