R merge и left_join выводят дублированные строки - PullRequest
0 голосов
/ 28 февраля 2020

У меня есть два фрейма данных с этой структурой:

> df_gen[1:5,]              
          Genus      mean_RA
1  Unclassified 0.1357401738
2 Lactobacillus 0.0003825068
3  Prevotella 9 0.0009573787
4  Anaerovibrio 0.0049035545
5     Roseburia 0.0026672558

> df_tax[1:8,]              
   Kingdom        Phylum         Class           Order           Family         Genus
1 Bacteria Bacteroidetes   Bacteroidia   Bacteroidales   Prevotellaceae  Prevotella 9
2 Bacteria Bacteroidetes   Bacteroidia   Bacteroidales   Prevotellaceae  Prevotella 9
3 Bacteria Bacteroidetes   Bacteroidia   Bacteroidales   Prevotellaceae  Prevotella 9 
4 Bacteria    Firmicutes       Bacilli Lactobacillales Lactobacillaceae Lactobacillus
5 Bacteria    Firmicutes Negativicutes Selenomonadales  Veillonellaceae  Anaerovibrio
6 Bacteria    Firmicutes Negativicutes Selenomonadales  Veillonellaceae  Anaerovibrio
7 Bacteria    Firmicutes       Bacilli Lactobacillales Lactobacillaceae Lactobacillus
8 Bacteria    Firmicutes    Clostridia   Clostridiales  Lachnospiraceae     Roseburia

Я хочу объединить df_gen с df_tax, но когда я все строки полностью дублирую, таким образом:

> merge(df_gen, df_tax, by = "Genus", all.x = TRUE)
          Genus      mean_RA  Kingdom        Phylum         Class           Order           Family
1  Unclassified 0.1357401738       NA            NA            NA              NA               NA
2 Lactobacillus 0.0003825068 Bacteria    Firmicutes       Bacilli Lactobacillales Lactobacillaceae
3 Lactobacillus 0.0003825068 Bacteria    Firmicutes       Bacilli Lactobacillales Lactobacillaceae
4  Prevotella 9 0.0009573787 Bacteria Bacteroidetes   Bacteroidia   Bacteroidales   Prevotellaceae
5  Prevotella 9 0.0009573787 Bacteria Bacteroidetes   Bacteroidia   Bacteroidales   Prevotellaceae
6  Prevotella 9 0.0009573787 Bacteria Bacteroidetes   Bacteroidia   Bacteroidales   Prevotellaceae
7  Anaerovibrio 0.0049035545 Bacteria    Firmicutes Negativicutes Selenomonadales  Veillonellaceae
8  Anaerovibrio 0.0049035545 Bacteria    Firmicutes Negativicutes Selenomonadales  Veillonellaceae
9     Roseburia 0.0026672558 Bacteria    Firmicutes    Clostridia   Clostridiales  Lachnospiraceae

Я не знаю, почему все в x дублируется в соответствии с количеством повторений в y. Мой желаемый вывод должен иметь тот же размер строки, что и df_gen, добавляя столбцы из df_tax.

Я пробовал также с dplyr::left_join, и у меня возникает та же проблема.

I проверил другие сообщения на inte rnet, но я не нашел ничего, чтобы решить эту проблему ... Любые подсказки?

Ответы [ 3 ]

2 голосов
/ 28 февраля 2020

Функция работает должным образом, она объединяет каждую строку с df_tax на df_gen, и, поскольку в df_tax имеется несколько значений, соответствующих значению df_gen, вы получаете несколько строк. df_tax имеет дублированные строки, вот в чем проблема.

1 голос
/ 28 февраля 2020

И merge(x, y, all.x=TRUE), и left_join(x, y) сохранят все строки из x независимо от того, имеют ли они совпадение по y, поэтому в основном эти команды предотвращают отбрасывание несовпадающих строк в x, но не избегают многократного сопоставления. Если у y есть дубликаты в ключевой переменной (в вашем случае, «Genus»), и они имеют совпадение по x, вы получите дубликаты. С точки зрения логики c это имеет смысл: какая из двух дублированных строк в y должна совпадать? Функция не имеет возможности узнать, поэтому она соответствует обоим. Если вы хотите получить файл с тем же номером строки df_genus, вам нужен df_tax, чтобы не было дубликатов. Если строки с дублированным родом идентичны и по отношению к другим переменным, вы можете go вдоль строки комментария с помощью r.user.05apr: df_tax_unique <- df_tax[!duplicated(df_tax$Genus), ]: при этом останется только первая из дублированных строк. Если строки имеют один и тот же род, но отличаются по отношению к другой переменной, вам нужно принять решение в соответствии с вашими потребностями: вы можете увеличить df_genus или удалить из df_tax строки, которые вы не хотите добавлять в df_genus.

0 голосов
/ 28 февраля 2020

В качестве решения вашей проблемы вы могли бы написать функцию, которая match es в строках, похожую на эту:

matchRows <- function(df1, df2, by) {
  do.call(rbind, apply(df1, 1, function(x) {
    m <- match(x[[by]], df2[[by]])
    `rownames<-`(cbind(t(x), df2[m, -which(names(df2) == by)]), NULL)
  }))}

matchRows(df1=df_gen, df2=df_tax, by="Genus")
#           Genus      mean_RA  Kingdom        Phylum         Class           Order           Family
# 1  Unclassified 0.1357401738     <NA>          <NA>          <NA>            <NA>             <NA>
# 2 Lactobacillus 0.0003825068 Bacteria    Firmicutes       Bacilli Lactobacillales Lactobacillaceae
# 3   Prevotella9 0.0009573787 Bacteria Bacteroidetes   Bacteroidia   Bacteroidales   Prevotellaceae
# 4  Anaerovibrio 0.0049035545 Bacteria    Firmicutes Negativicutes Selenomonadales  Veillonellaceae
# 5     Roseburia 0.0026672558 Bacteria    Firmicutes    Clostridia   Clostridiales  Lachnospiraceae

Данные:

df_gen <- structure(list(Genus = c("Unclassified", "Lactobacillus", "Prevotella9", 
"Anaerovibrio", "Roseburia"), mean_RA = c(0.1357401738, 0.0003825068, 
0.0009573787, 0.0049035545, 0.0026672558)), row.names = c(NA, 
-5L), class = "data.frame")

df_tax <- structure(list(Kingdom = c("Bacteria", "Bacteria", "Bacteria", 
"Bacteria", "Bacteria", "Bacteria", "Bacteria", "Bacteria"), 
    Phylum = c("Bacteroidetes", "Bacteroidetes", "Bacteroidetes", 
    "Firmicutes", "Firmicutes", "Firmicutes", "Firmicutes", "Firmicutes"
    ), Class = c("Bacteroidia", "Bacteroidia", "Bacteroidia", 
    "Bacilli", "Negativicutes", "Negativicutes", "Bacilli", "Clostridia"
    ), Order = c("Bacteroidales", "Bacteroidales", "Bacteroidales", 
    "Lactobacillales", "Selenomonadales", "Selenomonadales", 
    "Lactobacillales", "Clostridiales"), Family = c("Prevotellaceae", 
    "Prevotellaceae", "Prevotellaceae", "Lactobacillaceae", "Veillonellaceae", 
    "Veillonellaceae", "Lactobacillaceae", "Lachnospiraceae"), 
    Genus = c("Prevotella9", "Prevotella9", "Prevotella9", "Lactobacillus", 
    "Anaerovibrio", "Anaerovibrio", "Lactobacillus", "Roseburia"
    )), row.names = c(NA, -8L), class = "data.frame")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...