挑战:比较化学名称与排序和连接

时间:2016-03-19 05:48:47

标签: bash python-2.7 csv awk

我拥有的:

包含TSVCSV格式data.txt格式的名称和化验读数的文件:

Name,readout_1,readout_2,readout_3
A,98.0,-12.3,0.9
G,32.1,9.1,34.5
X,45.1,-2.3,56.7

另一个包含TSVCSV格式ref.txt格式的名称和化合物ID的文件:

Name,Compound_ID
A,1234
B,1235
C,1236
...
Z,3456

我想要的是什么:

我需要根据匹配的名称在另一列中将化合物ID添加到data.txt,即:

Name,readout_1,readout_2,readout_3,Compound_ID
A,98.0,-12.3,0.9,1234
G,32.1,9.1,34.5,1240
X,45.1,-2.3,56.7,3454

挑战:

我处理的化学名称可能很长,可能包含破折号,空格字符,逗号,括号,数字......,例如

2-acetoxybenzoic acid
N-(4-hydroxyphenyl)ethanamide
2-[(2S,5R,8S,11S)-5-benzyl-11-{3-[(diaminomethylidene)amino]propyl}-7-methyl-3,6,9,12,15-pentaoxo-8-(propan-2-yl)-1,4,7,10,13-pentaazacyclopentadecan-2-yl]acetic acid

两个文件中都有名称;虽然我还没有找到可行的解决方案。我尝试使用sortjoin,直到名称包含空格字符,然后join会抱怨违规行未排序。

如果可能的话,我更喜欢bashpythonawk中的解决方案,因为我在这里有一个基本的理解。

编辑:

在我的帖子中不清楚道歉。一些澄清:

我使用TSV,但认为在示例中使用CSV会更清楚,因为逗号比标签更容易辨别。

在示例中没有使用实际名称的道歉;再次,这样做是为了使示例简单。第三个示例名称显示名称可以有多长,这甚至不是特别长。

最后,我认为我的问题根植于某些化学名称中的空格字符。我在使用join时没有意识到忽略空格的选项。

3 个答案:

答案 0 :(得分:1)

这个简单的bash命令应该可以工作:

$ join -t , data.txt ref.txt
Name,readout_1,readout_2,readout_3,Compound_ID
A,98.0,-12.3,0.9,1234
G,32.1,9.1,34.5,1240
X,45.1,-2.3,56.7,3454

答案 1 :(得分:1)

唯一的问题是,当您的输入文件以逗号分隔时,您的真实姓名可以包含逗号。你在样本输入中根本没有表示这一点,你的2个输入文件中的id也不匹配所以这里更类似于你应该为样本输入和预期输出发布的内容:

http://localhost:8888/api/asdasdsadsad/css/bootstrap.min.css

即。上面的4个“名称”可以包含逗号本身,并且是$ cat data.txt Name,readout_1,readout_2,readout_3 A,3,17,35 A,3,98.0,-12.3,0.9 G,2,7,32.1,9.1,34.5 X,Y,Z,1,45.1,-2.3,56.7 $ cat ref.txt Name,Compound_ID A,9999 A,3,1234 G,2,7,1235 X,Y,Z,1,3456 AA,3G,2,7,这里是脚本加输出:

X,Y,Z,1

请注意,我在输出的$ cat tst.awk BEGIN { FS=OFS="," } FNR==1 { numVals = NF-1 } { match($0,"(.*),(([^,]+(,|$)){"numVals"})$",a) name = a[1] vals = a[2] } NR==FNR { ref[name] = vals; next } { print "\"" name "\"", vals, ref[name] } $ awk -f tst.awk ref.txt data.txt "Name",readout_1,readout_2,readout_3,Compound_ID "A",3,17,35,9999 "A,3",98.0,-12.3,0.9,1234 "G,2,7",32.1,9.1,34.5,1235 "X,Y,Z,1",45.1,-2.3,56.7,3456 字段周围添加了引号,因此结果是有效的CSV文件。

以上使用GNU awk作为第3个arg到name。使用其他awks,您只需使用2 match() s:

sub()

答案 2 :(得分:0)

感谢所有回复的人,并感谢Ed坚持认为join不会关心空间。

我的问题是数据排序不正确,导致join报告我的输入没有排序;见下文。

数据文件:

$ cat test_data.txt
Acebutolol hydrochloride    0.904   0.146   0.134   -0.196
Aconitine   -0.558  -0.471  -0.13   -0.332

按错误顺序排序的参考文件:

$ cat test_ref_S1.txt
ACACETIN    CDRD-00116180-01
ACACETIN DIACETATE  CDRD-00118610-01
ACEBUTOLOL HYDROCHLORIDE    CDRD-00115573-01
ACECLOFENAC CDRD-00115696-01
ACEMETACIN  CDRD-00115788-01
ACENOCOUMAROL   CDRD-00115657-01
ACETAMIDE   CDRD-00116997-01
ACETAMINOPHEN   CDRD-00116365-01
ACETYL ISOALLOGAMBOGIC ACID CDRD-00118740-01
ACETYL ISOGAMBOGIC ACID CDRD-00119007-01
ACETYL TYROSINE ETHYL ESTER CDRD-00118256-01
ACETYLSALICYLIC ACID    CDRD-00117028-01
ACETYLSALICYLSALICYLIC ACID CDRD-00115640-01
ACETYLTHIOCHOLINE CHLORIDE  CDRD-00117030-01
ACETYLTRYPTOPHAN    CDRD-00117996-01
ACETYLTRYPTOPHANAMIDE   CDRD-00118894-01
ACEXAMIC ACID   CDRD-00118338-01
ACIVICIN    CDRD-00116623-01
ACONITIC ACID   CDRD-00117968-01
ACONITINE   CDRD-00116111-01

现在排序正确:

$ sort -k1 -t $'\t' -V -f test_ref_S1.txt > test_ref_S2.txt
$ cat test_ref_S2.txt 
ACACETIN    CDRD-00116180-01
ACACETIN DIACETATE  CDRD-00118610-01
ACEBUTOLOL HYDROCHLORIDE    CDRD-00115573-01
ACECLOFENAC CDRD-00115696-01
ACEMETACIN  CDRD-00115788-01
ACENOCOUMAROL   CDRD-00115657-01
ACETAMIDE   CDRD-00116997-01
ACETAMINOPHEN   CDRD-00116365-01
ACETYLSALICYLIC ACID    CDRD-00117028-01
ACETYLSALICYLSALICYLIC ACID CDRD-00115640-01
ACETYLTHIOCHOLINE CHLORIDE  CDRD-00117030-01
ACETYLTRYPTOPHANAMIDE   CDRD-00118894-01
ACETYLTRYPTOPHAN    CDRD-00117996-01
ACETYL ISOALLOGAMBOGIC ACID CDRD-00118740-01
ACETYL ISOGAMBOGIC ACID CDRD-00119007-01
ACETYL TYROSINE ETHYL ESTER CDRD-00118256-01
ACEXAMIC ACID   CDRD-00118338-01
ACIVICIN    CDRD-00116623-01
ACONITIC ACID   CDRD-00117968-01
ACONITINE   CDRD-00116111-01

检查区别:

$ diff test_ref_S1.txt test_ref_S2.txt 
9,11d8
< ACETYL ISOALLOGAMBOGIC ACID   CDRD-00118740-01
< ACETYL ISOGAMBOGIC ACID   CDRD-00119007-01
< ACETYL TYROSINE ETHYL ESTER   CDRD-00118256-01
15d11
< ACETYLTRYPTOPHAN  CDRD-00117996-01
16a13,16
> ACETYLTRYPTOPHAN  CDRD-00117996-01
> ACETYL ISOALLOGAMBOGIC ACID   CDRD-00118740-01
> ACETYL ISOGAMBOGIC ACID   CDRD-00119007-01
> ACETYL TYROSINE ETHYL ESTER   CDRD-00118256-01

最后,加入文件:

$ join -a1 -1 1 -2 1 -t $'\t' -i test_data.txt test_ref_S2.txt > out.txt
join: test_ref_S2.txt:13: is not sorted: ACETYLTRYPTOPHAN   CDRD-00117996-01
$ cat out.txt 
Acebutolol hydrochloride    0.904   0.146   0.134   -0.196  CDRD-00115573-01
Aconitine   -0.558  -0.471  -0.13   -0.332  CDRD-00116111-01

ACETYLTRYPTOPHAN没有正确分类,因为它应该高于ACETYLTRYPTOPHANAMIDE,但我还没有能够解决这个问题。