如何在Nextflow中将列表转换为字典以映射groupKey
问题
在Nextflow中,有一个Channel对象chr_frequency,执行chr_frequency.toList().view()输出如下格式的列表:
[[chr1, 70], [chr2, 50], [chr3, 45]]
需要将其转换为键值对字典格式,用于后续和groupKey映射:
[ "chr1": 70, "chr2": 50, "chr3": 45 ]
相关业务代码如下:
test.out.map { chr, bcf -> tuple( groupKey(chr, chr_frequency[chr]), bcf.flatten() ) }.groupTuple( by: 0 ).view()
尝试以下两种方法均报错:
- 方法一:
chr_frequency .flatten() .view() chr21 3 chr22 3 .toSpreadMap()
报错信息:"Missing process or function toSpreadMap()"
- 方法二:
chr_frequency .collate(2).collectEntries().view()
报错信息:"Missing process or function collectEntries()"
使用环境:Ubuntu 22.04,OpenJDK版本"11.0.22" 2024-01-16
解决方案
报错原因是混淆了Nextflow Channel操作和Groovy集合方法:toSpreadMap()和collectEntries()都是Groovy集合(比如List、Map)的方法,不能直接用于Nextflow的Channel对象。
针对需求,有两种可行实现方式:
方式一:将Channel转为List后用Groovy方法构建字典
先把Channel转为Groovy List,再用collectEntries()生成字典:
def chr_freq_map = chr_frequency.toList().get(0).collectEntries { [it[0], it[1]] } chr_freq_map.view()
解释:
chr_frequency.toList()返回包含单个List元素的Channel,用.get(0)取出内部列表collectEntries { [it[0], it[1]] }将每个子列表[chr, count]转为字典键值对
方式二:用Channel的reduce操作构建字典
如果需要保持Channel类型(而非转为Groovy集合),可以用reduce逐步构建映射:
def chr_freq_channel = chr_frequency.reduce([:]) { map, entry -> map[entry[0]] = entry[1] map } chr_freq_channel.view()
解释:
- 初始值传入空字典
[:] - 每次迭代将Channel中的
[chr, count]条目添加到字典中
之后可直接在业务代码中使用:
// 用方式一的字典 test.out.map { chr, bcf -> tuple( groupKey(chr, chr_freq_map[chr]), bcf.flatten() ) }.groupTuple( by: 0 ).view() // 用方式二的Channel chr_freq_channel.flatMap { map -> test.out.map { chr, bcf -> tuple( groupKey(chr, map[chr]), bcf.flatten() ) } }.groupTuple( by: 0 ).view()
内容的提问来源于stack exchange,提问作者user3214212
相关产品推荐
相关产品推荐

