Сравнение двух столбцов в фрейме данных для совпадений и из этого создание нового фрейма данных, который содержит совпадения - PullRequest
0 голосов
/ 16 апреля 2020

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

У меня есть фрейм данных, который содержит 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, но мои навыки ограничены.

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

Ответы [ 3 ]

1 голос
/ 16 апреля 2020

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

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

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

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

0 голосов
/ 16 апреля 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")
0 голосов
/ 16 апреля 2020

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

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

...