R语言按ID分组拼接多行值及重复值处理问题
问题:按ID分组拼接行值及进阶处理
初始需求:按ID分组拼接列值
我需要实现仅对同一ID的行进行列值拼接,而非全部行拼接。相关参考思路来自行拼接的实现,但未找到分组方式。
目标输入
input <- data.frame(ID = c(1,1,1,3,3,3), X1 = c("A", 1, 11, "D", 4, 44), X2 = c("B", 2, 22, "E", 5, 55), X3 = c("C", 3, 33, "F", 6, 66))
目标输出
output <- data.frame(ID = c(1,3), X1 = c("A-1-11", "D-4-44"), X2 = c("B-2-22", "E-5-55"), X3 = c("C-3-33", "F-6-66"))
尝试的错误代码
直接使用现有方案会拼接全部6行,不符合按ID分组的需求:
output_v1 <- data.table::rbindlist(list(input, data.table::setDT(input)[, lapply(.SD, paste, collapse='-')]))
进阶需求:区分列值是否重复,按需拼接
初始问题已解决,但数据存在更复杂的情况:同一ID下某列值完全相同时保留单个值,否则拼接所有值(例如K-K-0保留拼接,I-I-I简化为I)。
目标输入
input2 <- data.frame(ID = c(1,1,1,3,3,3), X1 = c("A", 1, 11, "D", 4, 44), X2 = c("B", 2, 22, "E", 5, 55), X3 = c("C", 3, 33, "F", 6, 66), X4 = c("G", "G", "G", "H", 8, 88), X5 = c("I", "I", "I", "J", "J", "J"), X6 = c("K", "K", "0", "L", "L", "L"))
目标输出
output2 <- data.frame(ID = c(1,3), X1 = c("A-1-11", "D-4-44"), X2 = c("B-2-22", "E-5-55"), X3 = c("C-3-33", "F-6-66"), X4 = c("G", "H-8-88"), X5 = c("I", "J"), X6 = c("K-K-0", "L"))
尝试的代码及问题
尝试先识别需要拼接的列,再分别处理,但仅对完全重复的列(如X5)有效,无法正确处理X4、X6这类部分重复的列:
# 识别同一ID下有差异的列 changes <- input2 |> group_by(ID) |> mutate(across(everything(), ~n_distinct(.x) > 1)) |> pivot_longer(-ID, names_to = "col", values_to = "changed") |> filter(changed) |> select(-changed) |> distinct() # 分别处理拼接和去重 data_concat <- input2 |> as_tibble() |> group_by(ID) |> select(changes$col) |> summarise(across(everything(), list(function(col) str_flatten(col, ", ")))) data_unique <- input2 |> dplyr::select(!all_of(changes$col)) |> dplyr::distinct() data_new <- data_unique |> left_join(data_concat, by = 'ID')
附:若扩大问题范围不符合规范,可创建新问题。初始问题已解决。
内容的提问来源于stack exchange,提问作者KidLu
相关产品推荐
相关产品推荐

