Как в R удалить базы дубликатов на два столбца, значения которых, вероятно, можно обменять? - PullRequest
1 голос
/ 16 июня 2020

Мои образцы данных:

a <- data.frame(a1=c('a','b','c','d','e'),
                a2=c('b','a','d','c','f'),
                a3=c(0.1,0.3,0.5,0.1,1))

Я хочу объединить столбцы a1 и a2 и одновременно отсортировать строки. Итак, данные должны измениться на:

  a1 a2  a3  a12
1  a  b 0.1  a,b
2  b  a 0.3  a,b
3  c  d 0.5  c,d
4  d  c 0.1  c,d
5  e  f 1.0  e,f

После сортировки мы видим, что строки 1 и 2 фактически находятся в одной группе, как и строки 3 и 4. Затем для каждой группы я просто хочу сохранить ряд с самым большим a3. Итак, в конечном итоге данные должны быть такими:

  a1 a2  a3  a12
2  b  a 0.3  a,b
3  c  d 0.5  c,d
5  e  f 1.0  e,f

Я застрял на том, как отсортировать a1 и a2. Есть ли быстрый способ сделать это?

Ответы [ 3 ]

2 голосов
/ 16 июня 2020

Вы можете использовать sort и paste в apply, чтобы получить a12. Затем используйте which.max, чтобы получить строку, где a3 - максимальное значение, и верните это.

a$a12 <- apply(a[1:2], 1, function(x) paste(sort(x), collapse=","))
do.call(rbind, lapply(split(a, a$a12), function(x) x[which.max(x$a3),]))
#    a1 a2  a3 a12
#a,b  b  a 0.3 a,b
#c,d  c  d 0.5 c,d
#e,f  e  f 1.0 e,f
2 голосов
/ 16 июня 2020

Это то, что вам нужно:

library(dplyr)
library(tibble)

a <- tibble(a1=c('a','b','c','d','e'),
                a2=c('b','a','d','c','f'),
                a3=c(0.1,0.3,0.5,0.1,1))

a <- a %>%
  mutate(a12 = ifelse(a1 < a2, paste0(a1, ",", a2), paste0(a2, ",", a1))) %>%
  group_by(a12) %>%
  filter(a3 == max(a3))

> a
# A tibble: 3 x 4
# Groups:   a12 [3]
  a1    a2       a3 a12  
  <chr> <chr> <dbl> <chr>
1 b     a       0.3 a,b  
2 c     d       0.5 c,d  
3 e     f       1   e,f 
1 голос
/ 16 июня 2020

Вы можете отсортировать значения в столбцах a1 и a2, используя pmin и pmax, и сгруппировать их, чтобы выбрать значение max в каждой группе.

library(dplyr)
a %>%
   group_by(a11 = pmin(a1, a2), a22 = pmax(a1, a2)) %>%
   slice(which.max(a3)) %>%
   tidyr::unite(a12, a11, a22, sep = ',')

#   a1    a2     a3 a12  
#  <chr> <chr> <dbl> <chr>
#1 b     a       0.3 a,b  
#2 c     d       0.5 c,d  
#3 e     f       1   e,f  
...