Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Merge, concatenate, sort, intersect, and subset VCF files using bcftools. Use when combining variant files, comparing call sets, or restructuring VCF data.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 218% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 171% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 58% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 12% | 0% |
| case-19 | ✗→✓ | ▲ Improved | 88% | 0% |
<!--
#
#
-->
Merge, concat, sort, and compare VCF files using bcftools.
| Operation | Command | Use Case | |-----------|---------|----------| | Merge | bcftools merge | Combine samples from multiple VCFs | | Concat | bcftools concat | Combine regions from multiple VCFs | | Sort | bcftools sort | Sort unsorted VCF | | Intersect | bcftools isec | Compare/intersect call sets | | Subset | bcftools view | Extract samples or regions |
Combine multiple VCF files with different samples at the same positions.
bashbcftools merge sample1.vcf.gz sample2.vcf.gz -Oz -o merged.vcf.gz
bashbcftools merge *.vcf.gz -Oz -o all_samples.vcf.gz
bash# files.txt: one VCF path per line bcftools merge -l files.txt -Oz -o merged.vcf.gz
bash# Output missing genotypes as ./. (default) bcftools merge sample1.vcf.gz sample2.vcf.gz -Oz -o merged.vcf.gz # Output missing as reference (0/0) bcftools merge --missing-to-ref sample1.vcf.gz sample2.vcf.gz -Oz -o merged.vcf.gz
When sample names conflict:
bashbcftools merge --force-samples sample1.vcf.gz sample2.vcf.gz -Oz -o merged.vcf.gz
bashbcftools merge -r chr1:1000000-2000000 sample1.vcf.gz sample2.vcf.gz -Oz -o merged.vcf.gz
Combine VCF files with same samples from different regions.
bashbcftools concat chr1.vcf.gz chr2.vcf.gz chr3.vcf.gz -Oz -o genome.vcf.gz
bashbcftools concat chr*.vcf.gz -Oz -o genome.vcf.gz
bash# files.txt: one VCF path per line (in order) bcftools concat -f files.txt -Oz -o concatenated.vcf.gz
bashbcftools concat -a chr1_part1.vcf.gz chr1_part2.vcf.gz -Oz -o chr1.vcf.gz
bashbcftools concat -a -d all file1.vcf.gz file2.vcf.gz -Oz -o merged.vcf.gz
Options for -d:
snps - Remove duplicate SNPsindels - Remove duplicate indelsboth - Remove duplicate SNPs and indelsall - Remove all duplicatesexact - Remove exact duplicates onlySort VCF by chromosome and position.
bashbcftools sort input.vcf -Oz -o sorted.vcf.gz
For large files:
bashbcftools sort -T /tmp input.vcf.gz -Oz -o sorted.vcf.gz
bashbcftools sort -m 4G input.vcf.gz -Oz -o sorted.vcf.gz
Intersect and compare VCF files.
bashbcftools isec -p output_dir sample1.vcf.gz sample2.vcf.gz
Creates:
0000.vcf - Private to sample10001.vcf - Private to sample20002.vcf - Shared (sample1 records)0003.vcf - Shared (sample2 records)bashbcftools isec -p output_dir -Oz sample1.vcf.gz sample2.vcf.gz
bashbcftools isec -p output_dir -n=2 sample1.vcf.gz sample2.vcf.gz # Only outputs variants present in exactly 2 files
| Flag | Description | |------|-------------| | -n=2 | Present in exactly 2 files | | -n+2 | Present in 2 or more files | | -n-2 | Present in fewer than 2 files | | -n~11 | Boolean: file1 AND file2 | | -n~10 | Boolean: file1 AND NOT file2 |
bash# Variants in both files bcftools isec -n=2 -w1 sample1.vcf.gz sample2.vcf.gz -Oz -o shared.vcf.gz # Variants only in sample1 bcftools isec -n~10 -w1 sample1.vcf.gz sample2.vcf.gz -Oz -o only_sample1.vcf.gz
bash# Variants in file1 not in file2 bcftools isec -C sample1.vcf.gz sample2.vcf.gz -Oz -o unique.vcf.gz
bashbcftools view -s sample1,sample2 input.vcf.gz -Oz -o subset.vcf.gz
bashbcftools view -s ^sample3 input.vcf.gz -Oz -o without_sample3.vcf.gz
bash# samples.txt: one sample name per line bcftools view -S samples.txt input.vcf.gz -Oz -o subset.vcf.gz
bashbcftools view -r chr1:1000000-2000000 input.vcf.gz -Oz -o region.vcf.gz
bashbcftools view -R regions.bed input.vcf.gz -Oz -o targets.vcf.gz
bashecho "old_name new_name" > rename.txt bcftools reheader -s rename.txt input.vcf.gz -o renamed.vcf.gz
bash# rename.txt format: old_name new_name cat > rename.txt << EOF sample1 patient_001 sample2 patient_002 sample3 patient_003 EOF bcftools reheader -s rename.txt input.vcf.gz -o renamed.vcf.gz
bashfor sample in $(bcftools query -l input.vcf.gz); do bcftools view -s "$sample" input.vcf.gz -Oz -o "${sample}.vcf.gz" done
bashfor chr in $(bcftools view -h input.vcf.gz | grep "^##contig" | sed 's/.*ID=\([^,]*\).*/\1/'); do bcftools view -r "$chr" input.vcf.gz -Oz -o "${chr}.vcf.gz" done
bashbcftools norm -m-any input.vcf.gz -Oz -o split.vcf.gz
bash# Create file list ls *.vcf.gz > files.txt # Merge all samples bcftools merge -l files.txt -Oz -o cohort.vcf.gz bcftools index cohort.vcf.gz
bash# After parallel variant calling by chromosome bcftools concat chr{1..22}.vcf.gz chrX.vcf.gz chrY.vcf.gz -Oz -o genome.vcf.gz bcftools index genome.vcf.gz
bash# Find variants called by both GATK and bcftools bcftools isec -p comparison gatk.vcf.gz bcftools.vcf.gz # Count results wc -l comparison/*.vcf
bashbcftools view -f PASS input.vcf.gz -Oz -o pass_only.vcf.gz bcftools index pass_only.vcf.gz
Note: True VCF merging (combining samples at matching positions) is complex. Use bcftools merge for production work. cyvcf2 is better for filtering/querying.
pythonfrom cyvcf2 import VCF, Writer # WARNING: This concatenates records, not a true merge # For actual merging of samples, use bcftools merge vcf1 = VCF('file1.vcf.gz') writer = Writer('combined.vcf', vcf1) for variant in vcf1: writer.write_record(variant) writer.close() vcf1.close()
pythonfrom cyvcf2 import VCF # Load positions from first VCF vcf1_positions = set() for variant in VCF('sample1.vcf.gz'): vcf1_positions.add((variant.CHROM, variant.POS)) # Check second VCF shared = 0 unique = 0 for variant in VCF('sample2.vcf.gz'): if (variant.CHROM, variant.POS) in vcf1_positions: shared += 1 else: unique += 1 print(f'Shared: {shared}') print(f'Unique to sample2: {unique}')
| Task | Command | |------|---------| | Merge samples | bcftools merge s1.vcf.gz s2.vcf.gz -Oz -o merged.vcf.gz | | Concat regions | bcftools concat chr1.vcf.gz chr2.vcf.gz -Oz -o all.vcf.gz | | Sort VCF | bcftools sort input.vcf -Oz -o sorted.vcf.gz | | Intersect | bcftools isec -p dir a.vcf.gz b.vcf.gz | | Extract samples | bcftools view -s sample1 input.vcf.gz | | Rename samples | bcftools reheader -s names.txt input.vcf.gz |
| Error | Cause | Solution | |-------|-------|----------| | different samples | merge vs concat confusion | Use merge for samples, concat for regions | | not sorted | Unsorted input to concat | Sort first or use -a flag | | sample name conflict | Duplicate sample names | Use --force-samples | | index required | Missing index for merge/isec | Run bcftools index first |
<!-- AUTHOR_SIGNATURE: 9a7f3c2e-MD-BABU-MIA-2026-MSSM-SECURE -->
Other measured skills in the registry, with their headline benchmark lift.