r - 复杂的长到宽重塑算法
问题描述
我有一个问题,我需要将长格式数据表重塑为宽格式,其中包含基于 ID1 和 ID2 的不重叠条目。逻辑非常复杂,取决于 3 列(“Seq”、“ID1”和“ID2”)。
如果属于 ID1 的 Value_1 与 ID2“重叠”,则应将其相加,反之亦然,但仅适用于不同的 ID。
请参阅下面的输入示例和输出,希望能够澄清它。
输入:
df <- structure(list(Seq = c(9143L, 916L, 9293L, 9301L, 9302L, 9304L,
9305L, 9306L, 9307L, 931L, 9311L), ID1 = c("ID1_1", "ID1_1",
NA, "ID1_2", "ID1_2", NA, "ID1_3", "ID1_3", "ID1_3", "ID1_4",
"ID1_4"), value_1 = c(30L, 30L, NA, 30L, 30L, NA, 30L, 30L, 30L,
50L, 50L), ID2 = c(NA, NA, "ID2_1", "ID2_2", "ID2_3", "ID2_4",
"ID2_4", "ID2_4", "ID2_4", "ID2_4", "ID2_5"), value_2 = c(NA,
NA, 33L, 200L, 46L, 58L, 58L, 58L, 58L, 58L, 46L)), class = "data.frame", row.names = c(NA,
-11L))
输出:
(例如最后一行,value_1 = 80,因为 30+50 来自对 ID1_3 和 ID1_4 的值求和)
解决方案
我使用rleid()
了 data.table 包中的函数,这是一个计算运行长度编码的迷人函数。像这样做
library(data.table)
library(dplyr)
df %>%
mutate(d = cumsum( c(0, diff(rleid(ID1))) != 0 & c(0, diff(rleid(ID2))) != 0),
value_1 = value_1 * c(1, diff(rleid(ID1))),
value_2 = value_2 * c(1, diff(rleid(ID2)))) %>% group_by(d) %>%
summarise(Seq = toString(Seq),
value_1 = sum(value_1, na.rm = T),
value_2 = sum(value_2, na.rm = T)) %>%
ungroup() %>% select(-d)
# A tibble: 4 x 3
Seq value_1 value_2
<chr> <int> <int>
1 9143, 916 30 0
2 9293 0 33
3 9301, 9302 30 246
4 9304, 9305, 9306, 9307, 931, 9311 80 104
旧答案
df %>% group_by(d = cumsum( c(0, diff(rleid(ID1))) != 0 & c(0, diff(rleid(ID2))) != 0)) %>%
summarise(Seq = toString(Seq),
value_1 = sum(unique(value_1), na.rm = T),
value_2 = sum(unique(value_2), na.rm = T)) %>%
ungroup() %>% select(-d)
推荐阅读
- python - 访问任意维度的 Numpy 数组中的单个元素
- php - 未定义的数组键复选框html php
- c - 为什么在 OpenMP 中使用更多线程时时间会增加
- angular - 如何在单个组件中使用多个路由器插座
- python - 管道摄像机输出到两个进程
- c# - 如何将数据从授权选项卡转换为 Postman OAuth2 授权中的代码
- computer-vision - Yolov4 自定义训练 - 无法打开文件:data/msands.data
- java - 根据注释值保持全类
- nginx - 使用 Kubernetes nginx 入口进行多域设置
- validation - Codeigniter 4中的验证通过后为什么总是返回登录视图