Требуется дополнительное руководство по фильтрации всего кортежа на основе одного значения.
У меня есть канал кортежей (reads_ch):
[[id:S1, single_end:false], [/home/ubuntu/S1.R1.fastq.gz, /home/ubuntu/S1.R2.fastq.gz], /home/ubuntu/S1.txt, [PASSED: File S1_R1 is not corrupt., PASSED: File S1_R2 is not corrupt.]]
[[id:S2, single_end:false], [/home/ubuntu/S2.fastq.gz, /home/ubuntu/S2.R2.fastq.gz], /home/ubuntu/S2.txt, [PASSED: File S2_R1 is not corrupt., PASSED: File S2_R2 is not corrupt.]]
[[id:S3, single_end:false], [/home/ubuntu/S3.R1.fastq.gz, /home/ubuntu/S3.R2.fastq.gz], /home/ubuntu/S3.txt, [FAILED, FAILED]]
Я пытаюсь отфильтровать это для любого образца, который не «потерпел неудачу». Я добрался до его очистки[3], но так и не понял, как удалить этот образец. сохраняя при этом структуру остальных образцов (S1,S2)
Цель:
[[id:S1, single_end:false], [/home/ubuntu/S1.R1.fastq.gz, /home/ubuntu/S1.R2.fastq.gz], /home/ubuntu/S1.txt, [PASSED: File S1_R1 is not corrupt., PASSED: File S1_R2 is not corrupt.]]
[[id:S2, single_end:false], [/home/ubuntu/S2.fastq.gz, /home/ubuntu/S2.R2.fastq.gz], /home/ubuntu/S2.txt, [PASSED: File S2_R1 is not corrupt., PASSED: File S2_R2 is not corrupt.]]
Пытаться:
passing = read_ch.map { meta, reads, outcome_file, outcome_status ->
tuple(meta, reads, outcome_file, outcome_status.findAll { !it.contains('FAILED') })
}
passing.view()
[[id:S1, single_end:false], [/home/ubuntu/S1.R1.fastq.gz, /home/ubuntu/S1.R2.fastq.gz], /home/ubuntu/S1.txt, [PASSED: File S1_R1 is not corrupt., PASSED: File S1_R2 is not corrupt.]]
[[id:S2, single_end:false], [/home/ubuntu/S2.fastq.gz, /home/ubuntu/S2.R2.fastq.gz], /home/ubuntu/S2.txt, [PASSED: File S2_R1 is not corrupt., PASSED: File S2_R2 is not corrupt.]]
[[id:S3, single_end:false], [/home/ubuntu/S3.R1.fastq.gz, /home/ubuntu/S3.R2.fastq.gz], /home/ubuntu/S3.txt, []]





Предполагается, что весь элемент канала будет удален, даже если только одна выборка не удалась? Если это то, что вы хотите, вы найдете решение ниже:
Готовим фейковый канал, аналогичный вашему:
Channel
.of([
[id:'S1', single_end:false],
[file('/home/ubuntu/S1.R1.fastq.gz'), file('/home/ubuntu/S1.R2.fastq.gz')],
file('/home/ubuntu/S1.txt'),
['PASSED: File S1_R1 is not corrupt.', 'PASSED: File S1_R2 is not corrupt.']
],
[
[id:'S2', single_end:false],
[file('/home/ubuntu/S2.fastq.gz'), file('/home/ubuntu/S2.R2.fastq.gz')],
file('/home/ubuntu/S2.txt'),
['PASSED: File S2_R1 is not corrupt.', 'PASSED: File S2_R2 is not corrupt.']
],
[
[id:'S3', single_end:false],
[file('/home/ubuntu/S3.R1.fastq.gz'), file('/home/ubuntu/S3.R2.fastq.gz')],
file('/home/ubuntu/S3.txt'),
['FAILED', 'FAILED']
])
.set { my_ch }
Фильтрация:
my_ch
.filter { it[3].findAll { !it.contains('FAILED') } }
.view()
Выход:
Вы также можете сделать это следующим образом:
my_ch
.filter { it[3][0] != 'FAILED' && it[3][1] != 'FAILED' }
.view()
что позволяет легко адаптироваться, если вы хотите, чтобы один из них потерпел неудачу, а не оба.
Первое решение с contains уже делает это. Что касается второго, то можно .filter { !it[3][0].contains('FAILED') && !it[3][1].contains('FAILED') }
ДА ДА ДА! Это именно то, что я искал. и даже больше ДА для второго примера, фильтруя его по любому из двух местоположений it[3]. Есть ли способ сделать это еще более гибким, чтобы сделать ~= (содержит) «FAILED», а не «! = " (не равно)? Я думаю о сценарии, в котором мы пишем дополнительную информацию «FAILED DUE TO X», и в этом случае фильтрация не будет выполняться так, как мы ожидаем. В любом случае, СПАСИБО