r - 在 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:
有关预期矩阵(表),请参见上面的摘要
解决方案
这是一个基于我对您的数据结构的最佳猜测的解决方案(听起来很熟悉,因为我被免疫学家包围了)。关键是为每个源添加一个变量来跟踪源。然后可以将源 (list/data.frames) 组合成单个 data.frame 并进一步处理。
首先,为可重现的示例设置随机数种子。
set.seed(1234)
创建一个简化的人工数据集。这将包含 6 个源(列表/data.frames)。每个 data.frame 都有两个名为aa
和的变量clones
。aa
从 A、B 和 C 中随机选择的三个字母作为 12 个可能值中的每一个中的 CDR3 氨基酸。每个克隆的计数被存储clones
并设置为 10 到 20 之间的随机数。最后,为 6 个列表/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
source
为每个包含源名称的 list/data.frame添加一个名为的新变量。这很容易通过一个简单的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
现在,将每个 list/data.frames 合并到一个 data.frame 中,并使用变量source
跟踪哪个 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
推荐阅读
- android - 在 Kotlin 中将值格式化为人类可读形式的依赖性
- python - 分发 embed-cython-compiled .exe 并在没有 python 的情况下运行另一台机器
- node.js - 如何在运行时动态创建/修改 Angular 9 项目结构中的 sitemap.xml 文件?
- nix - nix-shell 的等效 shell.nix 是什么?
' - 一个 gnused - python - 如何使用python过滤时间序列或数据框中的日期范围
- java - 为什么我可以访问数组的索引,但是当我尝试使用索引初始化一个值时,它会给我一个 ArrayIndexOUtOfBoundException?
- php - 检查用户是否允许在 Wordpress 中注册
- algorithm - 如何判断变量何时超出范围?
- neo4j - 如何在阿蒙森并行化元摄取工作?
- laravel - 非复合名称 'Session' 的 use 语句无效