我有以下data.table
:
dt
# unique_id group_id primary_id ph1 ph2 ph3
# 1: 1 1 TRUE 07 03 <NA>
# 2: 2 1 FALSE 07 03 84
# 3: 3 2 FALSE 10 <NA> <NA>
# 4: 4 2 TRUE <NA> 10 <NA>
# 5: 5 2 FALSE <NA> <NA> 10
# 6: 6 3 FALSE 22 03 <NA>
# 7: 7 3 TRUE <NA> 13 03
unique_ids
按行之间通用的公用电话号码(ph1
,ph2
和ph3
)分组(例如,第一组“07”,“03”在整个组中是公用的,而在第三组中,“03”是共享的,但不在同一列中(按照第2组)。每组有1个
primary_id
。在每个组中,我想删除非primary_id中的公用电话号码元素,并将其保留为主要ID,以便不再链接它们。
我可以在for循环中轻松实现这一点,但是,它遍历了数百万个小组,而且非常慢。
寻找更快的方法。
数据:
library(data.table)
dt <- data.table(structure(list(unique_id = c(1, 2, 3, 4, 5, 6, 7), group_id = c(1,
1, 2, 2, 2, 3, 3), primary_id = c(TRUE, FALSE, FALSE, TRUE, FALSE,
FALSE, TRUE), ph1 = c("07", "07", "10", NA, NA, "22", NA), ph2 = c("03",
"03", NA, "10", NA, "03", "13"), ph3 = c(NA, "84", NA, NA, "10",
NA, "03")), class = "data.frame", row.names = c(NA, -7L))
)
所需的输出是:
output <- data.table(structure(list(unique_id = c(1, 2, 3, 4, 5, 6, 7), group_id = c(1,
1, 2, 2, 2, 3, 3), primary_id = c(TRUE, FALSE, FALSE, TRUE, FALSE,
FALSE, TRUE), ph1 = c("07", NA, NA, NA, NA, "22", NA), ph2 = c("03",
NA, NA, "10", NA, NA, "13"), ph3 = c(NA, "84", NA, NA, NA, NA,
"03")), class = "data.frame", row.names = c(NA, -7L)))
output
# unique_id group_id primary_id ph1 ph2 ph3
# 1: 1 1 TRUE 07 03 <NA>
# 2: 2 1 FALSE <NA> <NA> 84
# 3: 3 2 FALSE <NA> <NA> <NA>
# 4: 4 2 TRUE <NA> 10 <NA>
# 5: 5 2 FALSE <NA> <NA> <NA>
# 6: 6 3 FALSE 22 <NA> <NA>
# 7: 7 3 TRUE <NA> 13 03
如果仍然不清楚,则可以更容易地将其可视化,如下所示:
最佳答案
使用data.table
语法,以下内容将重现您的预期输出
dcast(
setorder(
melt(dt, id.vars = 1:3, measure.vars = 4:6),
group_id, -primary_id)[
which(duplicated(value)), value := NA, by = "group_id"],
unique_id + group_id + primary_id ~ variable, value.var = "value")
# unique_id group_id primary_id ph1 ph2 ph3
#1: 1 1 TRUE 07 03 <NA>
#2: 2 1 FALSE <NA> <NA> 84
#3: 3 2 FALSE <NA> <NA> <NA>
#4: 4 2 TRUE <NA> 10 <NA>
#5: 5 2 FALSE <NA> <NA> <NA>
#6: 6 3 FALSE 22 <NA> <NA>
#7: 7 3 TRUE <NA> 13 <NA>
说明:想法是将数据从宽到长整形,并按
group_id
和primary_id
排序条目(以primary_id == TRUE
首先出现);然后我们使用duplicated
(通过group_id
)标记重复的行,并将重复的条目设置为NA
,然后再次从宽变长。