【问题标题】:Assign numbers to each letter so that r calculates the sum of the letters in a word为每个字母分配数字,以便 r 计算单词中字母的总和
【发布时间】:2016-04-11 21:03:36
【问题描述】:

我正在尝试在 R 中创建一个工具,该工具将计算以单字母氨基酸代码输入的肽链的原子组成(即碳、氢、氮和氧原子的数量)。例如,肽 KGHLY 由氨基酸赖氨酸 (K)、甘氨酸 (G)、组氨酸 (H)、亮氨酸 (L) 和酪氨酸 (Y) 组成。赖氨酸由6个碳、13个氢、1个氮和2个氧组成。甘氨酸由2个碳、5个氢、1个氮和2个氧组成。等等等等 我希望 r 代码从数据帧中读取肽字符串 (KGHLY) 或使用 readline() 从键盘获取输入 我是 R 新手,也是编程新手。我能够为每种氨基酸制作对象,例如G

【问题讨论】:

  • 拆分字符串(使用strplit)然后使用match。如果您想在答案中使用代码,则需要制作一个小的、可重复的、说明性的示例。 See tips on that here。如果您使用模拟数据或使用dput() 共享数据,人们会很高兴。
  • 在这种情况下有用的是输入结构的样本(可能是肽向量和“成本”矩阵” - 氨基酸矩阵和每个元素的数量) ; 这或多或少是您在问题中描述的内容。dput 您问题中的这些数据,我认为我们可以为您提供一些代码

标签: r


【解决方案1】:

这里有两个主要部分需要注意: 一种存储基本数据的方法和算法 计算你想要的结果。

对于计算,最好有您的数据 由于 R 循环使用较短向量的方式,存储在矩阵中 当两个向量相乘时。如果您这样做,这种回收也会开始 想要将矩阵与向量相乘,因为矩阵是 带有一些附加属性的向量(即维度 和维度名称)。考虑下面的例子,看看它是如何 作品

test_matrix <- matrix(data = 1:12, nrow = 3)
test_vec <- c(3, 0, 1)

test_matrix
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12

test_matrix * test_vec
     [,1] [,2] [,3] [,4]
[1,]    3   12   21   30
[2,]    0    0    0    0
[3,]    3    6    9   12

根据这一观察,可以推断出一个解决方案 每个氨基酸在矩阵中都有一行可能是一个好方法 存储查找数据;当我们有一个计数向量 指定每行所需的贡献量,它 将我们的矩阵乘以我们的 计数就足够了 向量,然后对列求和 - 最后一部分使用 colSums.

colSums(test_matrix * test_vec)
[1]  6 18 30 42

一般来说,将这类信息存储在一个 矩阵,因为更新 稍后提供信息。但是,我想这不是经常 需要添加新的氨基酸,所以这可能不是问题 这个案例。

让我们为所需的五种氨基酸创建一个矩阵 对于您在示例中提到的肽。数字是 在维基百科上找到的,希望我在复制时没有搞砸 他们。只需照样添加所有其他氨基酸。

amino_acids <- rbind(
    G = c(C = 2, H = 5,  N = 1, O = 2),
    L = c(C = 6, H = 13, N = 1, O = 2),
    H = c(C = 6, H = 9,  N = 3, O = 2),
    K = c(C = 6, H = 14, N = 2, O = 2),
    Y = c(C = 9, H = 11, N = 1, O = 3))

amino_acids
  C  H N O
G 2  5 1 2
L 6 13 1 2
H 6  9 3 2
K 6 14 2 2
Y 9 11 1 3

这个矩阵包含我们想要的信息,但它可能是 最好按字典顺序排列它们——这将是 很高兴确保我们没有错误地添加同一行 两次。下面的代码解决了这两个问题。

amino_acids <-
    amino_acids[sort(unique(rownames(amino_acids))), ]

amino_acids                   
  C  H N O
G 2  5 1 2
H 6  9 3 2
K 6 14 2 2
L 6 13 1 2
Y 9 11 1 3

下一部分是弄清楚如何处理肽。这个 将在这里首先使用strsplit 来拆分字符串 分成单独的字符,然后在 result 得到我们要与矩阵相乘的向量。

peptide <- "KGHLY"

peptide_2 <- unlist(strsplit(x = peptide, split = ""))
peptide_2
[1] "K" "G" "H" "L" "Y"

在peptide_2 上使用table 给了我们

table(peptide_2)
peptide_2
G H K L Y 
1 1 1 1 1 

因此,这可以用来定义一个向量,在第一个示例中扮演test_vec 的角色。但是,通常生成的向量将包含比矩阵amino_acids 的行更少的分量;所以必须首先执行一个限制,以便获得我们想要的正确计算格式。

有多种选择,最简单的一种可能是使用表中的名称从amino_acids 中提取所需行的子集,这样计算就可以继续进行而无需任何进一步的模糊处理。

peptide_vec <- table(peptide_2)

colSums(amino_acids[names(peptide_vec), ] * as.vector(peptide_vec))
 C  H  N  O 
29 52  8 11

这概述了解决问题核心的一种可能解决方案, 这可以收集到一个处理所有问题的函数中 我们的步骤。

peptide_function <- function(peptide, amino_acids) {
    peptide_vec <- table(
        unlist(strsplit(x = peptide, split = "")))
    ## Compute the result and return it to the work flow.
    colSums(
        amino_acids[names(peptide_vec), ] *
        as.vector(peptide_vec))
}

最后是一个测试,看看我们得到了和以前一样的答案。

peptide_function(peptide = "GHKLY",
                 amino_acids = amino_acids)
 C  H  N  O 
29 52  8 11

接下来呢?好吧,这取决于您如何存储 肽,以及您想对结果做什么。如果为 例如,您将肽存储在向量中,并且想要 将结果存储在矩阵中,然后它可能例如是 可以使用vapply,如下所示。

data_vector <- c("GHKLY", "GGLY", "HKLGL")

result <- t(vapply(
    X = data_vector,
    FUN = peptide_function,
    FUN.VALUE = numeric(4),
    amino_acids = amino_acids))

result
       C  H N  O
GHKLY 29 52 8 11
GGLY  19 34 4  9
HKLGL 26 54 8 10

【讨论】:

  • 哇,非常感谢这个广泛的答案。我已经完成了您的示例并扩展了氨基酸和元素的数量以提供: data_vector
猜你喜欢
  • 2022-06-21
  • 1970-01-01
  • 2020-11-16
  • 1970-01-01
  • 2011-09-15
  • 2019-01-01
  • 1970-01-01
  • 2023-02-11
  • 2011-09-05
相关资源
最近更新 更多