2018년 12월 18일 화요일

[하루에 한 R] read.table() 함수가 컬럼 이름의 공백 또는 '-'을 '.'으로 자동으로 바꾸지 못하게 하려면

pyani로 생성한 ANI(Average Nucleotide Identity) marix를 가지고 heat map을 그리려 하였다. gplots 패키지의 heatmap.2() 함수를 쓰는 것이 내 실력 수준에서는 가장 자연스러운 선택이다. Row는 heatmap,2()가 알아서 클러스터링을 하게 만들었지만, column은 내가 원하는 방식으로 순서를 정하게 만들고 싶었다. 이번 시도에서는 dRep에서 따로 클러스터링을 한 결과를 가지고 column을 정렬하게 만들고자 하였다. pyani는 BLAST 혹은 MUMmer를 이용해서 ANI를 계산하는 반면, dRep의 2차 클러스터링에서는 gANI(ANIcalculator라고도 부른다)를 선택하여 쓸 수 있다. gANI는 whole-genome based ANI의 약자로서(NAR 논문 링크), bidirectional best hit로 확인된 상동 유전자 사이에 대해서 계산되는 값이라서 Konstantinos 등이 제안한 오리지널 ANI(PNAS 논문 링크)와는 조금 다르다.

ANIb_percentage_identity.tab 파일을 R로 읽어들여서 데이터프레임(data)을 만들었다. 다음으로 컬럼을 원하는 순서대로 정렬하기 위하여 dRep에서 만들어진 secondary clustering 결과에서 균주 명칭을 뽑은 뒤 이를 별도의 리스트에 넣었다. 이를 drep_order라 하자. 다음과 같이 치면 row는 원래대로이지만 column은 drep_order에 정의된 순서대로 정돈이 된다.
> data_new = data[, drep_order]
처음에는 이렇게 간단한 방법을 몰라서 무식하게도 for 구문을 사용했었다. 부끄러운 고백이지만 어제부터 방법을 찾다가 이 쉬운 기법을 오늘 발견하였다. 독학으로 R을 배우다 보면 늘 느끼는 것이지만 깨진 접시 모양으로 어딘가 이빨이 빠진 구석이 있다. 체계적인 학습이 되지 않았다는 것이다. 그런데 실행을 해 보면 이상하게도 그런 컬럼이 없다는 에러 메시지가 나오는 것이었다.
> data[,"Paenibacillus_peoriae_FSL_F8-0551"]
Error in `[.data.frame`(data, , "Paenibacillus_peoriae_FSL_F8-0551") :
  undefined columns selected
철자가 틀린 것이 없는데 왜 그럴까? 별의별 방법을 다 동원하여 컬럼 이름을 확인해 보니 43개 중에서 30개만 반환이 된다. 결국은 왜 이러한 불일치가 벌어졌는지를 알아낼 수 있었는데, 바로 파일을 데이터프레임으로 읽어들이면서 마이너스 기호('-')가 자동으로 마침표('.')로 바뀐 때문이었다. 이렇게 허탈할 데가 있나...



이렇게 자동적으로 변환을 하는 이유는 잘 모르겠다. 원본에 충실하게 읽어들이려면 read.table(x,...,check.names=FALSE)로 바꾸어야 한다. read.csv() 함수에서도 마찬가지이다. 컬럼 이름은 문법적으로도 맞아야 하고(그래서 마이너스 기호를 싫어하는지도 모른다) 중복이 되지 않는지도 따져야 한다. 한편으로는 수긍이 가는 정책이다. Row name은 건드리지 않으니 다행이다.

check.names 인자를 수정하여 파일을 읽어들였더니 컬럼 이름이 원본 파일에 있는 그대로 반영이 되었다. 이렇게 또 한 가지를 배웠다.

댓글 없음: