Связывание дубликатов со строкой для сохранения - PullRequest
0 голосов
/ 09 октября 2019

Использование следующего фрейма данных:

df <- data.frame(id=c(1324876,2457387,3136822,4607984,5049365,6395867,7847307,8347562,9283756), name=c("Anne","Jack","Bill","Mary","Bill","Mary","Anne","Jack","Mary"), cond1=c(1,0,0,1,0,0,1,1,0), cond2=c(0,1,0,0,1,1,1,0,0))
> df[order(df$name),]
       id name cond1 cond2
1 1324876 Anne     1     0
7 7847307 Anne     1     1
3 3136822 Bill     0     0
5 5049365 Bill     0     1
2 2457387 Jack     0     1
8 8347562 Jack     1     0
4 4607984 Mary     1     0
6 6395867 Mary     0     1
9 9283756 Mary     0     0

Допустим, я хочу сохранить только одну строку для имени. Я выберу, какую строку сохранить, основываясь на следующем порядке приоритета:

  1. Оба условия верны
  2. Условие 1 истинно
  3. Условие 2 истинно
  4. Ни то, ни другое

Теперь вместо добавления флага keep в строку, которую я хочу сохранить, как бы я сделал столбец keep_instead для каждого дубликата, который нужно удалить, содержащий id строки, которая будет сохранена? В этом случае мы получим следующее:

> df[order(df$name),]
       id name cond1 cond2 keep_instead
1 1324876 Anne     1     0      7847307
7 7847307 Anne     1     1           NA
3 3136822 Bill     0     0      5049365
5 5049365 Bill     0     1           NA
2 2457387 Jack     0     1      8347562
8 8347562 Jack     1     0           NA
4 4607984 Mary     1     0           NA
6 6395867 Mary     0     1      4607984
9 9283756 Mary     0     0      4607984

Ответы [ 3 ]

2 голосов
/ 09 октября 2019
library(dplyr)
df %>%
    group_by(name) %>%
    arrange(desc(cond1 * 2 + cond2)) %>%  #more weight to cond1
    mutate(keep_instead = if_else(row_number() > 1, first(id), NaN)) %>%
    ungroup() %>%
    arrange(name)
#> # A tibble: 9 x 5
#>        id name  cond1 cond2 keep_instead
#>     <dbl> <fct> <dbl> <dbl>        <dbl>
#> 1 7847307 Anne      1     1          NaN
#> 2 1324876 Anne      1     0      7847307
#> 3 5049365 Bill      0     1          NaN
#> 4 3136822 Bill      0     0      5049365
#> 5 8347562 Jack      1     0          NaN
#> 6 2457387 Jack      0     1      8347562
#> 7 4607984 Mary      1     0          NaN
#> 8 6395867 Mary      0     1      4607984
#> 9 9283756 Mary      0     0      4607984
0 голосов
/ 09 октября 2019
library(data.table)
setDT(df)

df[order(cond1, cond2, decreasing = T)
   , keep_instead := ifelse(1:.N > 1, id[1], NA)
   , by = name][order(name)]


#         id name cond1 cond2 keep_instead
# 1: 1324876 Anne     1     0      7847307
# 2: 7847307 Anne     1     1           NA
# 3: 3136822 Bill     0     0      5049365
# 4: 5049365 Bill     0     1           NA
# 5: 2457387 Jack     0     1      8347562
# 6: 8347562 Jack     1     0           NA
# 7: 4607984 Mary     1     0           NA
# 8: 6395867 Mary     0     1      4607984
# 9: 9283756 Mary     0     0      4607984
0 голосов
/ 09 октября 2019

мы можем использовать

library(dplyr)
library(stringr)
df %>% 
   arrange(name) %>%
   mutate(rn = row_number()) %>% 
   arrange(name, factor(str_c(cond1, cond2), 
               levels = c('11', '10', '01', '00'))) %>% 
   group_by(name) %>% 
   mutate(keep_instead = first(id)) %>% 
   arrange(name) %>%
   mutate(keep_instead = replace(keep_instead, !duplicated(keep_instead), NA))
# A tibble: 9 x 6
# Groups:   name [4]
#       id name  cond1 cond2    rn keep_instead
#    <dbl> <fct> <dbl> <dbl> <int>        <dbl>
#1 7847307 Anne      1     1     2           NA
#2 1324876 Anne      1     0     1      7847307
#3 5049365 Bill      0     1     4           NA
#4 3136822 Bill      0     0     3      5049365
#5 8347562 Jack      1     0     6           NA
#6 2457387 Jack      0     1     5      8347562
#7 4607984 Mary      1     0     7           NA
#8 6395867 Mary      0     1     8      4607984
#9 9283756 Mary      0     0     9      4607984
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...