对于学校的化学项目,我想计算所有可能的分子式组合的分子量,包括碳(1个原子到100),氧气(1到50),氢气(1到200),氮气( 1到20)和硫(1到10)并将结果保存在一个载体中,并将相应的分子式字符串保存在另一个载体中。质量是数值:12,16,1,14和32.字符串是" C"," O"," H"," N"," S"。
我想从字符串和相应的质量中删除无意义的分子式,如C1 O100 H0 N20 S10。因此更具体地说,只留下0到1之间的O / C关系,2和1之间的H / C关系,0和0.2之间的N / C关系以及0和0.1之间的S / C关系。
有没有一种简单的方法可以做到这一点,是使用for循环的唯一方法还是有更快的方法(可能是数组?)以及如何考虑分子关系?
对于解决此问题的一些想法或基本代码会有所不满。
..所以@Gregor在创建整个列表之前排除那些没有意义的原子关系可能会更好吗? @Barker是像氮这样的原子应该从0到最大。我是R的新手,所以当我尝试循环时,我最终计算出最后一个值...(减少了维数)。
z=matrix(0,1,5*20*10*2*2)
C=12
O=16
H=1
N=14
S=32
for( u in 1:length(z)) {
for(i in 1:5) {
for (j in 1:20) {
for(k in 1:10 ) {
for(l in 0:1) {
for(m in 0:1){
z[1,u] <- C*i+H*j+O*k+N*l+S*m
}
}
}
}
}
}
有谁知道这里的错误在哪里?
答案 0 :(得分:0)
expand.grid
是开始生成组合的好地方。例如,要创建一个包含H和C组合的data.frame
,您可以执行此操作
mol = expand.grid(C = 1:3, H = 1:4)
mol
# C H
# 1 1 1
# 2 2 1
# 3 3 1
# 4 1 2
# 5 2 2
# 6 3 2
# 7 1 3
# 8 2 3
# 9 3 3
# 10 1 4
# 11 2 4
# 12 3 4
您也可以添加expand.grid
中的其他元素,并将输入调整为1:200
或您想要的多少。如果您的计算机有足够的内存,您将能够创建问题中指定的10MM行数据框 - 尽管这是非常大的。如果你可以将组合总数减少到1MM,你的记忆就会容易得多。
下一步是删除不符合比率标准的行。这是一个例子,以确保H的数量是C的数量的1到2倍:
mol = mol[mol$H >= mol$C & mol$H <= 2 * mol$C, ]
mol
# C H
# 1 1 1
# 4 1 2
# 5 2 2
# 8 2 3
# 9 3 3
# 11 2 4
# 12 3 4
对所有条件重复这样的步骤。
最后,您可以计算权重并将其放入新列:
mol$weight = with(mol, C * 12 + H * 1)
mol
# C H weight
# 1 1 1 13
# 4 1 2 14
# 5 2 2 26
# 8 2 3 27
# 9 3 3 39
# 11 2 4 28
# 12 3 4 40
您可以使用矩阵乘法进行权重计算,但不需要使用少量可能的元素。如果您有20个或更多可能的输入元素,那么这样做是有意义的。
奖金!可以使用paste
或paste0
:
mol$formula = paste0("C", mol$C, " H", mol$H)
mol
# C H weight formula
# 1 1 1 13 C1 H1
# 4 1 2 14 C1 H2
# 5 2 2 26 C2 H2
# 8 2 3 27 C2 H3
# 9 3 3 39 C3 H3
# 11 2 4 28 C2 H4
# 12 3 4 40 C3 H4
当然,其中大部分仍然没有化学意义 - C1 H1并不是真正存在的东西,但也许你可以想出更聪明的条件来摆脱更多的不可能性!