Очистка дубликатов со ссылкой из другого фрейма данных - PullRequest
4 голосов
/ 11 апреля 2019

Я хочу избавиться от дубликатов, используя правильную информацию в другом фрейме данных.

Проблема в том, что исходные данные имеют дубликаты как с правильными значениями, так и с неправильными значениями.Правильные значения определены в другом фрейме данных, поэтому я хочу использовать этот фрейм данных в качестве ссылки для этих строк.

Так что задание, которое я хочу сделать условным для двух строк.Чтобы проиллюстрировать это, предположим, что исходные данные tree1:

tree1 = data.frame( 
sp = c("oak","pine","apple","birch","oak","pine","apple","maple"), 
code = c(23:26,77,88,99,27))
> tree1
     sp code
1   oak   23
2  pine   24
3 apple   25
4 birch   26
5   oak   77
6  pine   88
7 apple   99
8 maple   27

И справочные данные tree2:

tree2 = data.frame( sp = c("oak","pine","apple"),
                    code = 23:25)
> tree2
     sp code
1   oak   23
2  pine   24
3 apple   25

И мой желаемый вывод, от которого я избавляюсьдубликаты с неправильными значениями, где у меня все еще есть исходные данные, должны выглядеть следующим образом:

> tree3
     sp code
1   oak   23
2  pine   24
3 apple   25
4 birch   26
5 maple   27

Я знаю, что это кажется простой условной операцией, но я в итоге удалил некоторые исходные значения или сохранил дубликаты с неправильнымизначения в конце (наоборот не работает).Простая помощь R-base была бы хороша.

Ответы [ 5 ]

3 голосов
/ 11 апреля 2019

Один вариант с использованием базы R mapply.Предполагая, что у вас есть одинаковые столбцы в tree1 и tree2 и в том же порядке, мы можем проверить значения в tree1, которые присутствуют в tree2, и выбрать только те строки, в которых все значения совпадают или нет значений.

vals <- rowSums(mapply(`%in%`, tree1, tree2))
tree1[vals == ncol(tree1) | vals == 0, ]

#    sp  code
#1   oak   23
#2  pine   24
#3 apple   25
#4 birch   26
#8 maple   27
2 голосов
/ 11 апреля 2019

Вот вариант dplyr:

library(dplyr)
tree2bis <- filter(tree1, !(tree1$sp %in% tree2$sp)) # dataframe with no duplicated rows
tree1 %>% inner_join(tree2) %>% bind_rows(tree2bis)
# output
     sp code
1   oak   23
2  pine   24
3 apple   25
4 birch   26
5 maple   27
1 голос
/ 11 апреля 2019

Вы также можете сделать что-то подобное, используя data.table package-

> setDT(tree2)[setDT(tree1),on=.(sp)][!(duplicated(sp)),.(sp,i.code)]

     sp    i.code
1:   oak     23
2:  pine     24
3: apple     25
4: birch     26
5: maple     27
1 голос
/ 11 апреля 2019

Также возможна dplyr:

tree1 %>%
 filter(code %in% tree2$code | !sp %in% tree2$sp)

     sp code
1   oak   23
2  pine   24
3 apple   25
4 birch   26
5 maple   27

Или:

tree1 %>%
 left_join(tree2, by = c("sp" = "sp")) %>%
 filter(code.x == code.y | (!is.na(code.x) & is.na(code.y))) %>%
 transmute(sp = sp,
           code = code.x)

     sp code
1   oak   23
2  pine   24
3 apple   25
4 birch   26
5 maple   27

Или первая возможность в base R:

subset(tree1, code %in% tree2$code | !sp %in% tree2$sp)
1 голос
/ 11 апреля 2019

Полное избавление от дубликатов, так как соответствующие правильные значения в любом случае находятся во втором фрейме данных, и связывают эти строки

rbind(
  tree1[!(duplicated(tree1$sp) | duplicated(tree1$sp, fromLast = TRUE)), ],
  tree2
)
#>      sp code
#> 4 birch   26
#> 8 maple   27
#> 1   oak   23
#> 2  pine   24
#> 3 apple   25

Создано в 2019-04-11 пакетом представ. (v0.2.1)

...