我如何 merge/join 来自两个数据帧的多列,具体取决于匹配模式

How can I merge/join multiple columns from two dataframes, depending on a matching pattern

我想根据染色体列中的相似模式合并两个数据帧。我对 R & BASH 进行了各种尝试,例如“data.table”、“tidyverse”和 merge()。有人可以通过在 R、BASH、Python、Perl 等中提供替代解决方案来帮助我解决此解决方案吗?我想根据染色体信息进行合并,同时保留counts/RXNs.

注意:这两个 DF 没有对齐,我也很好奇如果缺少某些值会发生什么。

感谢和干杯:

DF1:

Chromosome;RXN;ID
1009250;q9hxn4;NA
1010820;p16256;NA
31783;p16588;"PNTOt4;PNTOt4pp"
203;3-DEHYDROQUINATE-DEHYDRATASE-RXN;"DHQTi;DQDH"

DF2:

Chromosome;Count1;Count2;Count3;Count4;Count5
203;1;31;1;0;0;0
1010820;152;7;0;11;4
1009250;5;0;0;17;0
31783;1;0;0;0;0;0

预期结果:

Chromosome;RXN;Count1;Count2;Count3;Count4;Count5
1009250;q9hxn4;5;0;0;17;0
1010820;p16256;152;7;0;11;4
31783;p16588;1;0;0;0;0
203;3-DEHYDROQUINATE-DEHYDRATASE-RXN;1;31;1;0;0;0

如果我正确理解您的要求,这应该在 Python 中完成。我已将 Chromosome 列放入每个 DataFrame 的索引中。

from io import StringIO

txt1 = '''Chromosome;RXN;ID
1009250;q9hxn4;NA
1010820;p16256;NA
31783;p16588;"PNTOt4;PNTOt4pp"
203;3-DEHYDROQUINATE-DEHYDRATASE-RXN;"DHQTi;DQDH"'''

txt2 = """Chromosome;Count1;Count2;Count3;Count4;Count5;Count6
203;1;31;1;0;0;0
1010820;152;7;0;11;4
1009250;5;0;0;17;0
31783;1;0;0;0;0;0"""

df1 = pd.read_csv(
    StringIO(txt1),
    sep=';',
    index_col=0,
    header=0
)

df2 = pd.read_csv(
    StringIO(txt2),
    sep=';',
    index_col=0,
    header=0
)
DF1:
                                         RXN               ID
Chromosome
1009250                               q9hxn4              NaN
1010820                               p16256              NaN
31783                                 p16588  PNTOt4;PNTOt4pp
203         3-DEHYDROQUINATE-DEHYDRATASE-RXN       DHQTi;DQDH

DF2:
            Count1  Count2  Count3  Count4  Count5  Count6
Chromosome
203              1      31       1       0       0     0.0
1010820        152       7       0      11       4     NaN
1009250          5       0       0      17       0     NaN
31783            1       0       0       0       0     0.0
result = pd.concat(
    [df1.sort_index(), df2.sort_index()],
    axis=1
)
print(result)
                                         RXN               ID  Count1  Count2  Count3  Count4  Count5  Count6
Chromosome
203         3-DEHYDROQUINATE-DEHYDRATASE-RXN       DHQTi;DQDH       1      31       1       0       0     0.0
31783                                 p16588  PNTOt4;PNTOt4pp       1       0       0       0       0     0.0
1009250                               q9hxn4              NaN       5       0       0      17       0     NaN
1010820                               p16256              NaN     152       7       0      11       4     NaN

concat 命令还可以通过简单地为列填充 NaN 值来处理不匹配的索引,例如df1 如果 df2 没有相同的索引,反之亦然。

由于正文中提到了bash,我为您提供一个awk解决方案。数据帧在文件 df1df2:

$ awk '
BEGIN {
    FS=OFS=";"         # input and output field delimiters
}
NR==FNR {              # process df1
    a[]=           # hash to an array, 1st is the key, 2nd the value
    next               # process next record
}
{                      # process df2
    =(a[] OFS )  # prepend RXN field to 2nd field of df2
}1' df1 df2            # 1 is output command, mind the file order

最后两行可能写得更清楚:

...
{
    print ,a[],,,,,
}' df1 df2

输出:

Chromosome;RXN;Count1;Count2;Count3;Count4;Count5
203;3-DEHYDROQUINATE-DEHYDRATASE-RXN;1;31;1;0;0;0
1010820;p16256;152;7;0;11;4
1009250;q9hxn4;5;0;0;17;0
31783;p16588;1;0;0;0;0;0

输出将按df2的顺序。 df1 中存在但 df2 中不存在的染色体将不包括在内。 df2 中但不在 df1 中的染色体将从 df2 输出,RXN 字段为空。另外,如果 df1 中有重复的染色体,则使用最后一条。如果这是一个问题,可以修复。