Сравнение двух столбцов во фрейме данных на наличие совпадений и создание нового фрейма данных, содержащего совпадения.

пожалуйста, вы можете мне помочь еще раз?

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

     mb_rank  mb_gene  ts_rank  ts_gene
[1]  1        BIRCA    1        MYCN
[2]  2        MYCN     2        MOB4
[3]  3        ATXN1    3        ABHD17C
[4]  4        ABHD17C  4        AEBP2
5 etc... for up to 6000 rows in some data sets. 
the ts columns are usually a lot longer than the mb columns. 

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

     mb_rank  mb_gene  ts_rank  ts_gene
[1]  2        MYCN     1        MYCN
[2]  4        ABHD17C  3        ABHD17C

В этом примере желаемого результата недублированные гены были удалены, остались только гены, которые изначально были в обоих списках.

Я пробовал много вещей, таких как:

`df[df$mb_gene %in% df$ts_gene,]` 

но это не работает и, кажется, попадает в какой-то ген 2) я пытался написать функцию IF, но мои навыки слишком ограничены.

Я надеюсь, что описал это достаточно хорошо, но если я могу что-то уточнить, пожалуйста, спрашивайте, я действительно застрял. Заранее спасибо!


person TobiasFirth    schedule 16.04.2020    source источник
comment
Пожалуйста, добавьте образцы данных с dput(head(df,n)) для лучшей воспроизводимости.   -  person NelsonGon    schedule 16.04.2020
comment
Извините, я не совсем уверен, что вы имеете в виду.   -  person TobiasFirth    schedule 16.04.2020
comment
это работает: df[df$mb_gene == df$ts_gene,]?   -  person bouncyball    schedule 16.04.2020
comment
Это более длинная версия моего комментария. По сути, в настоящее время не так просто воспроизвести ваш пример.   -  person NelsonGon    schedule 16.04.2020


Ответы (3)


В data.frame обычно строка представляет собой полное наблюдение, что означает, что все данные в ней коррелируют (каким-то образом) с остальными. В опросе одна строка — это либо один человек (все вопросы), либо один вопрос для одного человека. Однако в ваших данных здесь ваша первая строка BIRCA и MYCN полностью разделена, что означает, что вы хотите удалить одну, не удаляя другую. С точки зрения «науки о данных» это предполагает, что ваши данные имеют неправильную форму.

Для того, чтобы сделать то, что вы хотите, нам нужно разбить их на отдельные кадры.

df <- read.table(header = TRUE, stringsAsFactors = FALSE, text = "
mb_rank  mb_gene  ts_rank  ts_gene
1        BIRCA    1        MYCN
2        MYCN     2        MOB4
3        ATXN1    3        ABHD17C
4        ABHD17C  4        AEBP2")

df1 <- df[,1:2]
df2 <- df[,3:4]
df1
#   mb_rank mb_gene
# 1       1   BIRCA
# 2       2    MYCN
# 3       3   ATXN1
# 4       4 ABHD17C
df2
#   ts_rank ts_gene
# 1       1    MYCN
# 2       2    MOB4
# 3       3 ABHD17C
# 4       4   AEBP2

Отсюда мы можем использовать intersect для поиска общих генов:

incommon <- intersect(df1$mb_gene, df2$ts_gene)
df1[df1$mb_gene %in% incommon,]
#   mb_rank mb_gene
# 2       2    MYCN
# 4       4 ABHD17C
df2[df2$ts_gene %in% incommon,]
#   ts_rank ts_gene
# 1       1    MYCN
# 3       3 ABHD17C

Если вы на 100% уверены, что у вас всегда будет одинаковое количество строк в каждой из них, вы можете просто cbind их вместе:

cbind(
  df1[df1$mb_gene %in% incommon,],
  df2[df2$ts_gene %in% incommon,]
)
#   mb_rank mb_gene ts_rank ts_gene
# 2       2    MYCN       1    MYCN
# 4       4 ABHD17C       3 ABHD17C

Однако если есть вероятность, что в каждом будут разные числа, то вы столкнетесь с проблемами. Если число одного кратно другому, вы получите «переработку» данных и предупреждение, но вы все равно получите данные (что я считаю ошибкой):

cbind(
  df1[df1$mb_gene %in% incommon,],
  df2
)
# Warning in data.frame(..., check.names = FALSE) :
#   row names were found from a short variable and have been discarded
#   mb_rank mb_gene ts_rank ts_gene
# 1       2    MYCN       1    MYCN
# 2       4 ABHD17C       2    MOB4
# 3       2    MYCN       3 ABHD17C
# 4       4 ABHD17C       4   AEBP2

Однако, если не кратно, вы просто получите сообщение об ошибке:

cbind(
  df1[df1$mb_gene %in% incommon,],
  df2[1:3,]
)
# Error in data.frame(..., check.names = FALSE) : 
#   arguments imply differing number of rows: 2, 3

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

person r2evans    schedule 16.04.2020
comment
Хороший. Пожалуйста, примите это, если/когда у вас появится шанс. Спасибо! - person r2evans; 21.04.2020

Использование: df_new — ваш новый фрейм данных.

df_new = df[df['mb_gene'] == df['ts_gene']]

person kanna    schedule 16.04.2020

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

d1 = select(df, c(mb_rank, mb_gene))
d2 = select(df, c(ts_rank, ts_gene))
merge(d1, d2, by.x="mb_gene", by.y="ts_gene")
person F Trias    schedule 16.04.2020