在r中创建一个计数表(矩阵)

时间:2019-08-09 13:47:36

标签: r

我正在尝试根据一系列已转换为数据框的列表来开发表格。每个列表由字符串及其计数组成。每个字符串在7到20(或更多)之间变化。每个列表都有一个标头,用于标识字符串的来源。我有66个列表(来源)。每个列表包含5,000多个字符串。并非每个列表中都包含每个字符串,因此列表中的字符串数会有所不同。这是单个列表结构的示例。

$PreAg_18_2

CDR3.aa         Clones
 <chr>            <int>
CASSYGTAYTGELFF   1623
CASSRGDSDNSPLHF   1440
CASSREKAFF        1161
CSGMGALAKNIQYF     949
CSAYTGLSYEQYF      813
CASSLSLAVNSPLHF    634
CAIRDTPGSPQHF      574
CATGQVNTEAFF       555
CASSLKGQGGSPLHF    499
CASSYSRSPQPQHF     478

我想将结果合并到一个表中,该表显示计数(克隆)以及y轴上列出的所有字符串(CDR3.aa)和x轴上的每个列表标头(Sample.Id)。一个例子是:

            10_pep_10_1     preAg_10_2      Dec_2_18_1  …... 
CASSYGTAYTGELFF    1623         234             0
CASSRGDSDNSPLHF    1440         522             28
CASSREKAFF         1161         445             50  
CSGMGALAKNIQYF      949         24              0
CASSYSRSPQPQHF      478         0               398
.
.

我能够生成包含示例中的的单个列表,并且我认为将列表转换为数据帧是一种更好的操纵它们的方法,但是我很难将它们合并为一个所有字符串的单个列表,并将sample.id移动到x轴。我想取消列出所有字符串并将它们加入一个df,但是我不确定如何使计数与字符串匹配。 R中是否有功能可以帮助我做到这一点?还是不可避免地要形成循环?

到目前为止,我已经能够生成字符串的全局列表,但是现在我需要按标头(sample.id)匹配计数。不确定如何解决这个问题。

    library(immunarch)
    library(stringr)
    library(plyr)

    immdata = repLoad("/mnt/data/Development/Analysis_Script/input_files/")

    all <- immdata$data

    # Get list headers (names)
    sample.id <- names(all)

    # make new variable for extraction of clones
    all.c <- all

    # Get list of clones and filter for unique clones per list.
    for (i in 1:length(all.c)){
        all.c[[i]]$Sample.ID<-names(all.c)[i]
        all.c[[i]]<-all.c[[i]][,c("CDR3.aa", "Clones")]
    }


    # bysamp is a list (vector) of the samples and their clones
    bysamp <- split(all.c, sample.id, sep=" ")

    # make vector of all clones
    all.clones <- unlist(all.c, use.names=FALSE)

    # a list of the aggregate of all the clones in all the samples.
    all.clones

    # Removes clone repeats
    all.clones.u <- unique(all.clones)

    # convert list of clones and sample.ids to data frame
    all.clones.u <- data.frame(all.clones.u)
    sample.id <- data.frame(sample.id)

    # Addtional code here:

有关预期矩阵(表),请参见上面的摘要

1 个答案:

答案 0 :(得分:0)

这是一个基于我对数据结构的最佳猜测的解决方案(由于我被免疫学家包围,这听起来很熟悉)。 键是向每个源添加一个变量,该变量将跟踪源。然后,可以将源(列表/数据框架)组合为一个数据框架并进行进一步处理。

首先,为可重现的示例设置一个随机数种子。

  set.seed(1234)

创建简化的人工数据集。。该数据集由6个来源(list / data.frames)组成。每个data.frame具有两个名为aaclones的变量。在12个可能的aa值中,每个都从A,B和C中随机选择三个字母作为CDR3氨基酸。每个克隆的计数存储在clones中,并设置为10到20之间的随机数。最后,为6个list / data.frames中的每一个命名。我使用的是source_1,source_2等,而不是“ 10_pep_10_1”。

希望这已经复制了您面对的数据。通过仅使用3种可能的氨基酸,该示例可确保同一序列在不同列表中出现几次的可能性很高。

# generate sample data
  spl <- replicate(6, { # the braces '{}' define an expression to be repeated
      n <- 12 # number of aa values in each list
      aa <- replicate(n,
        paste(sample(LETTERS[1:3], 3, replace = T), collapse = ""))
      clones <- sample(10:20, n, replace = T)
      data.frame(aa, clones)}, # this is the 'return' value of the expression
    simplify = FALSE) # this ensures that the result remains as a list

# name each list
  names(spl) <- paste("source", seq_along(spl), sep = "_")

检查6个数据帧中的第一个。

  head(spl$source_1)
>    aa clones
> 1 ABB     12
> 2 BCB     12
> 3 AAB     20
> 4 BCB     18
> 5 ACA     16
> 6 CAA     17

向每个包含源名称的list / data.frame添加一个名为source的新变量。使用简单的for循环即可轻松完成此操作。在第一个data.frame中显示更改。

  for (i in seq_along(spl)) spl[[i]]$source <- names(spl)[i]

  head(spl$source_1) # or head(spl[[1]])
>    aa clones   source
> 1 ABB     12 source_1
> 2 BCB     12 source_1
> 3 AAB     20 source_1
> 4 BCB     18 source_1
> 5 ACA     16 source_1
> 6 CAA     17 source_1

现在,使用变量source将每个list / data.frame组合到一个data.frame中,以跟踪哪个list / data.frame贡献了值。然后使用基本函数计算每个肽(clones)和aa的数目(source)。存储在res中的结果是另一个data.frame。由此将生成一个列联计数表。通常,这被合并为一个步骤。有关更多信息,请参见aggregate()的帮助文件。此类数据整理的一种流行方法是使用dplyr包。

  dat <- do.call(rbind, spl)

  res <- aggregate(clones ~ aa + source, dat, sum)
  tbl <- xtabs(clones ~ aa + source, res)

# this operation is rather common and often is done in one line:
  tbl <- xtabs(clones ~ ., aggregate(clones ~ ., dat, sum))

  head(tbl, 10)
>      source
> aa    source_1 source_2 source_3 source_4 source_5 source_6
>   AAA       29        0       46        0        0       14
>   AAB       20        0        0        0        0        0
>   ABB       12       14       13        0        0        0
>   ACA       16       23       16        0        0        0
>   ACB       13       19       15        0        0        0
>   BAA       17        0        0       55       16       33
>   BAC       15       19       19        0       34        0
>   BCB       30        0        0       68       38       15
>   CAA       17       11        0        0        0        0
>   CCA       15        0        0        0        0        0

表中条目的顺序很简单,即rbind期间继承的顺序。可以通过重新组织表格来改变它。在这里,行被排序。

  ord <- order(rownames(tbl))
  head(tbl[ord,], 10)
>      source
> aa    source_1 source_2 source_3 source_4 source_5 source_6
>   AAA       29        0       46        0        0       14
>   AAB       20        0        0        0        0        0
>   AAC        0       19       19        0        0       31
>   ABA        0       11        0        0       15       18
>   ABB       12       14       13        0        0        0
>   ACA       16       23       16        0        0        0
>   ACB       13       19       15        0        0        0
>   ACC        0       11       16        0       15        0
>   BAA       17        0        0       55       16       33
>   BAB        0       15        0        0        0        0