之前的博客提到,R语言处理大数据效率较低,耗时长,一种解决方案是可以转用Python语言流程,但如果对Python语言比较陌生,任务又急,那可以采用另一种方案——分组随机取样。
尽管Seurat这个软件包功能极其强大,但是当细胞数达到几十万甚至上百万时,把常规流程跑一遍少则几天,多则几周,实在是极其消耗时间。而且有时吧,只是单纯想测试一下某些参数或者流程是否可用,如果用全数据集来测试实在有点浪费时间,所有可用考虑分组随机选取细胞数进行分析。
这里封装了一个函数sample_seob,以下是参数解释:
sample_seob <- function(obj,group.by="seurat_clusters",sp.size=NULL,diet="true",sp.total=1000) {
all <- obj
if (diet=="true") {
all <- DietSeurat(all)
}
if (is.null(sp.size)) {
nlen <- length(unique(all@meta.data[,group.by]))
sp.size <- ceiling(sp.total/nlen)
}
seob_list <- list()
i <- 1
for (sc in unique(all@meta.data[,group.by])){
cellist <- colnames(all)[which(all@meta.data[,group.by] == sc)]
ob <- subset(all, cells=cellist)
if (length(colnames(ob)) > sp.size) {
ob <- subset(ob,cells=sample(colnames(ob), sp.size))
}
seob_list[[i]] <- ob
i <- i+1
}
all <- Reduce(merge,seob_list)
return(all)
}
数据集采用Seurat内置数据集pbmc_small,有80个细胞,按RNA_snn_res.1分组有3种类型
> pbmc_small
An object of class Seurat
230 features across 80 samples within 1 assay
Active assay: RNA (230 features, 20 variable features)
2 dimensional reductions calculated: pca, tsne
> unique(pbmc_small$RNA_snn_res.1)
[1] 0 2 1
Levels: 0 1 2
使用sp.size=10,按RNA_snn_res.1分组,每种类型取10个细胞。
> all <- sample_seob(pbmc_small,sp.size=10,group.by='RNA_snn_res.1')
> all
An object of class Seurat
230 features across 30 samples within 1 assay
Active assay: RNA (230 features, 0 variable features)
使用sp.total=50,按RNA_snn_res.1分组,取大约50个细胞。
> all <- sample_seob(pbmc_small,sp.total=50,group.by='RNA_snn_res.1')
> all
An object of class Seurat
230 features across 51 samples within 1 assay
Active assay: RNA (230 features, 0 variable features)
在实际的分析中,我发现FindAllMarkers经常跑着跑着就断了,出现以下报错:
Warning: When testing 15 versus all:
The total size of the 5 globals that need to be exported for the future expression (‘FUN()’) is 2.06 GiB. This exceeds the maximum allowed size of 500.00 MiB (option 'future.globals.maxSize'). The three largest globals are ‘data.use’ (2.06 GiB of class ‘S4’), ‘group.info’ (2.56 MiB of class ‘list’) and ‘FUN’ (9.76 KiB of class ‘function’).
这种情况一般是因为数据集太大了,由运行内存不足导致,这种情况目前找到的解决办法是随机取样后找DEG,结果也比较可靠,运行起来也快很多。以下是示例封装的函数**subset_deg **,部分参数与上面一致,其它参数与FindAllMarkers一致。
subset_deg <- function(obj,group.by="seurat_clusters",sp.size=NULL,output="./",
min.pct=0.25,logfc.threshold=0.25,only.pos=F,assays ="RNA",order=F) {
all <- DietSeurat(obj)
if (!is.null(sp.size)) {
seob_list <- list()
i <- 1
for (sc in unique(all@meta.data[,group.by])){
cellist <- colnames(all)[which(all@meta.data[,group.by] == sc)]
ob <- subset(all, cells=cellist)
if (length(colnames(ob)) > sp.size) {
ob <- subset(ob,cells=sample(colnames(ob), sp.size))
}
seob_list[[i]] <- ob
i <- i+1
}
all <- Reduce(merge,seob_list)
}
all_markers <- FindAllMarkers(all, only.pos = only.pos, min.pct = min.pct, logfc.threshold = logfc.threshold, verbose = F,assays = assays,order=order)
write.table(all_markers, paste0(output, "deg_sample",sp.size,".xls"),sep="\t",quote=F)
}
也可以简写成下面的形式:
subset_deg <- function(obj,group.by="seurat_clusters",sp.size=NULL,output="./",
min.pct=0.25,logfc.threshold=0.25,only.pos=F,assays ="RNA",order=F,diet="true",sp.total=1000) {
all <- sample_seob(obj, sp.size=sp.size,group.by=group.by,diet=diet,sp.total=sp.total)
all_markers <- FindAllMarkers(all, only.pos = only.pos, min.pct = min.pct, logfc.threshold = logfc.threshold, verbose = F,assays = assays,order=order)
write.table(all_markers, paste0(output, "deg_sample",sp.size,".xls"),sep="\t",quote=F)
}
因为上面的版本循环里每次都要subset,太麻烦了,最后还要merge一下,比较耗时间,因此修改代码为下面的结果,只需要subset一次,也不用merge,能较快得到结果。
Sample_seob <- function(obj,group.by="seurat_clusters",sp.size=NULL,diet="true",sp.total=1000) {
all <- obj
if (diet=="true") {
all <- DietSeurat(all,dimreducs = c('pca','umap'))
}
if (is.null(sp.size)) {
nlen <- length(unique(all@meta.data[,group.by]))
sp.size <- ceiling(sp.total/nlen)
}
ncellist <- c()
for (sc in unique(all@meta.data[,group.by])){
cellist <- colnames(all)[which(all@meta.data[,group.by] == sc)]
if (length(cellist) > sp.size) {
cellist=sample(cellist, sp.size)
}
ncellist <- c(ncellist,cellist)
}
all <- subset(all,cells=ncellist)
return(all)
}
突然看到官网有函数是能简便实现这种分组随机取细胞数的,转换Idents后就能根据Idents信息分类别随机选取细胞。
Idents(pbmc) <- "orig.ident"
# Downsample the number of cells per identity class
ob1 <- subset(x = pbmc, downsample = 100)
不多说了,搬砖去了。祝大家六一儿童节快乐!
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
假设我有一个在Ruby中看起来像这样的哈希:{:ie0=>"Hi",:ex0=>"Hey",:eg0=>"Howdy",:ie1=>"Hello",:ex1=>"Greetings",:eg1=>"Goodday"}有什么好的方法可以将它变成如下内容:{"0"=>{"ie"=>"Hi","ex"=>"Hey","eg"=>"Howdy"},"1"=>{"ie"=>"Hello","ex"=>"Greetings","eg"=>"Goodday"}} 最佳答案 您要求一个好的方法来做到这一点,所以答案是:一种您或同事可以在六个月后理解
我想在ruby中生成一个64位整数。我知道在Java中你有很多渴望,但我不确定你会如何在Ruby中做到这一点。另外,64位数字中有多少个字符?这是我正在谈论的示例......123456789999。@num=Random.rand(9000)+Random.rand(9000)+Random.rand(9000)但我认为这是非常低效的,必须有一种更简单、更简洁的方法来做到这一点。谢谢! 最佳答案 rand可以将范围作为参数:pa=rand(2**32..2**64-1)#=>11093913376345012184putsa.
我已经有很多两个值数组,例如下面的例子ary=[[1,2],[2,3],[1,3],[4,5],[5,6],[4,7],[7,8],[4,8]]我想把它们分组到[1,2,3],[4,5],[5,6],[4,7,8]因为意思是1和2有关系,2和3有关系,1和3有关系,所以1,2,3都有关系我如何通过ruby库或任何算法来做到这一点? 最佳答案 这是基本Bron–Kerboschalgorithm的Ruby实现:classGraphdefinitialize(edges)@edges=edgesenddeffind_maximum_
如果至少有两个相邻的数字相同,格式为,我需要打包.这是我的输入:[2,2,2,3,4,3,3,2,4,4,5]以及预期的输出:"2:3,3,4,3:2,2,4:2,5"到目前为止我试过:a=[1,1,1,2,2,3,2,3,4,4,5]a.each_cons(2).any?do|s,t|ifs==t如果相等,也许可以尝试计数器,但那是行不通的。 最佳答案 您可以使用Enumerable#chunk_while(如果你使用的是Ruby>=2.3):a.chunk_while{|a,b|a==b}.flat_map{|chunk|chu
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:HowdoIgeneratealistofnuniquerandomnumbersinRuby?我想做的事:Random.rand(0..10).timesdoputsRandom.rand(0..10)end但如果随机数已经显示过,则无法再次显示。如何最轻松地做到这一点?
我试图在每次运行时以随机顺序将一个名称数组拆分为多个数组。我知道如何拆分它们:name_array=["bob","john","rob","nate","nelly","michael"]array=name_array.each_slice(2).to_a=>[["bob","john"],["rob","nate"],["nelly","michael"]]但是,如果我希望它每次都以随机顺序吐出它们怎么办? 最佳答案 在做同样的事情之前,打乱数组。(Array#shuffle)name_array.shuffle.each_s
我有一个文件,每一行都有数字:010110101311010113114311010431420我想要一个包含每个数字出现次数的散列,在这种情况下:{0101=>2,1010=>2,1311=>2,431=>2,420=>1}我该怎么做? 最佳答案 简单的一行代码,给定一个数组items:items.inject(Hash.new(0)){|hash,item|hash[item]+=1;hash}工作原理:Hash.new(0)创建一个新的Hash,其中访问未定义的键返回0。inject(foo)使用给定的block遍历数组。对于
3月26日,映宇宙(HK:03700,即“映客”)发布截至2022年12月31日的2022年度业绩财务报告。财报显示,映宇宙2022年的总营收为63.19亿元,较2021年同期的91.76亿元下降31.1%。2022年,映宇宙的经营亏损为4698.7万元,2021年同期则为净利润4.57亿元;期内亏损(净亏损)为1.68亿元,2021年同期的净利润为4.33亿元;非国际财务报告准则经调整净利润为3.88亿元,2021年同期为4.82亿元,同比下降19.6%。 映宇宙在财报中表示,收入减少主要是由于行业竞争加剧,该集团对旗下产品采取更为谨慎的运营策略以应对市场变化。不过,映宇宙的毛利率则有所提升