I'll be making some assumptions here. You don't specify what "3" indicates for your genotypes, so I coded it as the default missing genotype for Plink (0). I'm using "R" and "A" as simply shorthand for "Reference" and "Alternate" alleles; plink can read these characters just fine. You'd need to edit the dictionary below if you need it to do something else.
This script essentially transposes the first line of your input to create the columns required in the .map file. It reads the second line to get the chromosome number. The third column is left at the default dummy value of "0" because centimorgans is unknown.
The ped file is generated by converting genotypes from your numeric values to what I'm assuming they represent (again, defined in the python dictionary), including the first six required columns (see https://www.cog-genomics.org/plink2/formats#fam for specifics). Importantly, the FID is simply repeating the IID because I don't know relatedness here. IID (individual ID) is just the row number (1st row is ind_1, 2nd row is ind_2, etc. This is fine so long as the order is identical between your different chromosome files. Phenotype is set to the "missing" value of -9. Format is fine on the test files shown below.
#!/usr/bin/env python
import sys
infile_name = sys.argv[1]
pedDict = {
"0" : "R R",
"1" : "R A",
"2" : "A A",
"3" : "0 0"
}
def convertToPlink(infile_name):
with open(infile_name, 'r') as infile:
header = infile.readline().rstrip().split()
chromosome = infile.readline().split()[0]
with open('chr_' + chromosome + '.map', 'w') as mapfile:
for POS in header[1:]:
mapfile.write("\t".join([chromosome, chromosome+"_"+POS+"_SNP", "0", POS])+"\n")
with open(infile_name, 'r') as infile:
with open('chr_' + chromosome + '.ped', 'w') as pedfile:
id_index = 0
for line in infile:
if not line.startswith("CHR"):
id_index += 1
IID = "ind_" + str(id_index)
line = line.rstrip().split()
pedfile.write(" ".join([IID, IID, "0", "0", "0", "-9"]+[pedDict[genotype] for genotype in line][1:])+ "\n")
convertToPlink(infile_name)
test input: chr_1.txt
CHR 59 100 130 165
1 3 1 2 3
1 3 0 2 1
1 0 0 1 0
1 0 3 3 1
1 1 1 0 2
executing
convertToPlink.py chr_1.txt
yields two plink-compatible files:
chr_1.map
1 1_59_SNP 0 59
1 1_100_SNP 0 100
1 1_130_SNP 0 130
1 1_165_SNP 0 165
chr_1.ped
ind_1 ind_1 0 0 0 -9 0 0 R A A A 0 0
ind_2 ind_2 0 0 0 -9 0 0 R R A A R A
ind_3 ind_3 0 0 0 -9 R R R R R A R R
ind_4 ind_4 0 0 0 -9 R R 0 0 0 0 R A
ind_5 ind_5 0 0 0 -9 R A R A R R A A