세 개의 열이 있는 데이터세트가 있습니다.
https://drive.google.com/file/d/1gtCssfAXHxRjGfX8uTAaimGPWCA2cnci/view?usp=sharing
처음 몇 줄은 다음과 같습니다.
ID transcript_id go_description
MA_10000213g0010 MA_10000213g0010
MA_10000405g0010 MA_10000405g0010 GO:0006468-protein phosphorylation;GO:0030246-carbohydrate binding;GO:0005524-ATP binding;GO:0004672-protein kinase activity
MA_1000049g0010 MA_1000049g0010
MA_10000516g0010 MA_10000516g0010 GO:0005515-protein binding
MA_10001015g0010 MA_10001015g0010
MA_10001337g0010 MA_10001337g0010
MA_10001425g0010 MA_10001425g0010
MA_10001478g0010 MA_10001478g0010
MA_10001558g0010 MA_10001558g0010
MA_10001g0010 MA_10001g0010
MA_10002030g0010 MA_10002030g0010 GO:0005737-cytoplasm;GO:0000184-nuclear-transcribed mRNA catabolic process, nonsense-mediated decay;GO:0004386-helicase activity;GO:0008270-zinc ion binding;GO:0003677-DNA binding;GO:0005524-ATP binding
MA_10002157g0010 MA_10002157g0010 GO:0006468-protein phosphorylation;GO:0005524-ATP binding;GO:0004672-protein kinase activity
MA_10002549g0010 MA_10002549g0010
MA_10002583g0010 MA_10002583g0010 GO:0008168-methyltransferase activity
MA_10002614g0010 MA_10002614g0010
MA_10002643g0010 MA_10002643g0010 GO:0055114-oxidation-reduction process
GO:xxxxxxx
세 번째 열에서는 각 용어를 쉼표로 구분해야 하는 부분을 제외한 모든 텍스트를 제거하고 싶습니다 . 예를 들어:
GO:0006468, GO:0030246
처음 두 열은 변경되지 않은 상태로 유지되어야 합니다. 어떻게 해야 하나요?
답변1
데이터가 탭으로 구분되어 있다고 가정하면 다음과 같이 할 수 있습니다.
perl -F'\t' -lane '
$F[2] = join(",", $F[2]=~/GO:\d+/g);
print join "\t",@F
' gene_table_Go\ -\ gene_table_Go.tsv > fixed.tsv
make는 각 입력 행을 주어진 문자의 배열 로 분할 -a
하는 nd perl
와 유사하게 작동합니다 . 여기서는 탭을 전달합니다. 아직 파일을 저장하지 않았다면 언제든지 탭으로 구분된 파일로 저장할 수 있습니다. 다음으로, 세 번째 필드를 기존 세 번째 필드에서 뒤따르는 모든 숫자를 연결한 결과 로 설정합니다 . 즉, GO 용어만 유지하고 다른 것은 아무것도 유지하지 않습니다. 그런 다음 탭으로 연결된 배열을 인쇄합니다 .awk
@F
-F
$F[2]
GO:
@F
다음은 동일한 기본 아이디어를 더욱 압축한 버전입니다.
perl -F'\t' -lane '
$,="\t";
print @F[0..1], join(",",$F[2]=~/GO:\d+/g);
' gene_table_Go\ -\ gene_table_Go.tsv
두 예제 모두 동일한 출력을 생성합니다.
$ perl -F'\t' -lane '$,="\t"; print @F[0,1], join(",",$F[2]=~/GO:\d+/g);' gene_table_Go\ -\ gene_table_Go.tsv | head
ID transcript_id
MA_10000213g0010 MA_10000213g0010
MA_10000405g0010 MA_10000405g0010 GO:0006468,GO:0030246,GO:0005524,GO:0004672
MA_1000049g0010 MA_1000049g0010
MA_10000516g0010 MA_10000516g0010 GO:0005515
MA_10001015g0010 MA_10001015g0010
MA_10001337g0010 MA_10001337g0010
MA_10001425g0010 MA_10001425g0010
MA_10001478g0010 MA_10001478g0010
MA_10001558g0010 MA_10001558g0010
GO:\d+
헤더 가 실제로 패턴과 일치하지 않기 때문에 헤더를 그대로 유지하려면 다음을 수행할 수 있습니다.
$ perl -F'\t' -lane '$,="\t"; print $. == 1 ? @F : @F[0,1], join(",",$F[2]=~/GO:\d+/g);' gene_table_Go\ -\ gene_table_Go.tsv | head
ID transcript_id go_description
MA_10000213g0010 MA_10000213g0010
MA_10000405g0010 MA_10000405g0010 GO:0006468,GO:0030246,GO:0005524,GO:0004672
MA_1000049g0010 MA_1000049g0010
MA_10000516g0010 MA_10000516g0010 GO:0005515
MA_10001015g0010 MA_10001015g0010
MA_10001337g0010 MA_10001337g0010
MA_10001425g0010 MA_10001425g0010
MA_10001478g0010 MA_10001478g0010
MA_10001558g0010 MA_10001558g0010
답변2
AWK:
$ awk '
BEGIN{FS=OFS="\t"}
{
while(match($3,/GO:[0-9]+/))
{
col= sprintf("%s",((col) ? col ",": "")substr($3,RSTART,RLENGTH));
$3= substr($3,RSTART+RLENGTH)
}
}
col{ $3=col; col=""}
1'
답변3
사용행복하다(이전 Perl_6)
\t
탭을 열 구분자로 가정 :
~$ raku -ne 'BEGIN put get; \
my @a = .split(:skip-empty, / \t /, 3); \
@a[2] = (@a[2] // "").comb(/ GO\: \d+ /).join(","); \
@a.join("\t").trim-trailing.put;' file
이것은 Perl 프로그래밍 언어 중 하나인 Raku로 작성된 답변입니다. 한 줄씩 진행하십시오.
BEGIN
머리글 행에 대한 설명( 본문 행과 같이put
머리글 행이\t
탭으로 구분된 경우 생략 가능)본문 라인(행)을 분할 하여 배열
\t
로 저장할 수 있습니다. 4개의 연속 공백 문자 또는 심지어 (4개의 연속 공백 문자) 로@a
분할하는 것이 가능하지만 위험합니다.\s**4
\h**4
수평의공백 문자) 세 번째 열에 패턴이 포함되어 있지 않은 경우. 그러나 또 위험이 있습니다.세 번째 열(예: ) 은 정규 표현식과 일치하는 하나 이상에 대해 편집된(즉, 긍정적으로 선택) 열 텍스트
@a[2]
로 대체됩니다 . 생각은 그 반대입니다 (파괴적입니다). 그런 다음 선택한 -ID를 쉼표로 연결합니다 .@a[2]
comb
GO\: \d+
comb
split
GO
마지막으로
split
탭join
에서 열이 다시 그룹화되어\t
출력됩니다put
.
입력 예:
ID transcript_id go_description
MA_10000213g0010 MA_10000213g0010
MA_10000405g0010 MA_10000405g0010 GO:0006468-protein phosphorylation;GO:0030246-carbohydrate binding;GO:0005524-ATP binding;GO:0004672-protein kinase activity
MA_1000049g0010 MA_1000049g0010
MA_10000516g0010 MA_10000516g0010 GO:0005515-protein binding
MA_10001015g0010 MA_10001015g0010
MA_10001337g0010 MA_10001337g0010
MA_10001425g0010 MA_10001425g0010
MA_10001478g0010 MA_10001478g0010
MA_10001558g0010 MA_10001558g0010
MA_10001g0010 MA_10001g0010
MA_10002030g0010 MA_10002030g0010 GO:0005737-cytoplasm;GO:0000184-nuclear-transcribed mRNA catabolic process, nonsense-mediated decay;GO:0004386-helicase activity;GO:0008270-zinc ion binding;GO:0003677-DNA binding;GO:0005524-ATP binding
MA_10002157g0010 MA_10002157g0010 GO:0006468-protein phosphorylation;GO:0005524-ATP binding;GO:0004672-protein kinase activity
MA_10002549g0010 MA_10002549g0010
MA_10002583g0010 MA_10002583g0010 GO:0008168-methyltransferase activity
MA_10002614g0010 MA_10002614g0010
MA_10002643g0010 MA_10002643g0010 GO:0055114-oxidation-reduction process
예제 출력:
ID transcript_id go_description
MA_10000213g0010 MA_10000213g0010
MA_10000405g0010 MA_10000405g0010 GO:0006468,GO:0030246,GO:0005524,GO:0004672
MA_1000049g0010 MA_1000049g0010
MA_10000516g0010 MA_10000516g0010 GO:0005515
MA_10001015g0010 MA_10001015g0010
MA_10001337g0010 MA_10001337g0010
MA_10001425g0010 MA_10001425g0010
MA_10001478g0010 MA_10001478g0010
MA_10001558g0010 MA_10001558g0010
MA_10001g0010 MA_10001g0010
MA_10002030g0010 MA_10002030g0010 GO:0005737,GO:0000184,GO:0004386,GO:0008270,GO:0003677,GO:0005524
MA_10002157g0010 MA_10002157g0010 GO:0006468,GO:0005524,GO:0004672
MA_10002549g0010 MA_10002549g0010
MA_10002583g0010 MA_10002583g0010 GO:0008168
MA_10002614g0010 MA_10002614g0010
MA_10002643g0010 MA_10002643g0010 GO:0055114
답변4
당신은 사용을 고려할 수 있습니다밀러, TSV 파일에 대한 지원이 내장되어 있습니다.
$go_description
필드를;
배열로 분할GO:nnnnnn
정규식을 적용하여 배열의 각 요소에서 하위 문자열을 추출합니다.- 결과를 다시
,
단일 문자열 로 연결 - 결과를 다시 할당
$go_description
그래서
mlr --tsv put '
$go_description = joinv(
apply(splitax($go_description,";"),func(e) {return regextract(e,"GO:[[:digit:]]+")}),
","
)
' gene_table_Go.tsv