2019년 2월 8일 금요일

[하루에 한 R] read.table() 함수는 왜 #로 시작하는 라인을 읽지 못하는가?

데이터를 텍스트 형태로 수록한 자료 파일에서 주석(comment) 라인은 보통 첫번째 글자를 '#'으로 시작하는 경우가 많다. Shell 혹은 Perl script에서 주석을 달 때 쓰는 관행을 그대로 답습하는 것으로 보인다.

자료 파일의 중간에 주석을 넣을 수도 있지만, CSV(comma-separated values) 파일에서는 첫 줄에 컬럼의 이름에 해당하는 정보를 담기도 한다. antiSMASH database에서 다운로드한 파일의 사례를 보자. 확장자는 csv지만 실제 구분자는 탭이다. 첫 줄은 컬럼의 이름 정보를 싣는 동시에 '#'로 시작함으로서 주석임을 명시하였다.


이것을 read.table("file.csv",sep="\t",header=T)로 읽으면 어떻게 될까? '#Genus', 'Species', 'Strain'...이 컬럼 이름으로 들어가는 일은 절대로 벌어지지 않는다. 첫줄이 '#'로 시작하면 comment로 인식하여 읽어들이는 과정에서 그냥 지나가기 때문이다.

이를 제대로 읽으려면 다음과 같은 명령을 써야 한다.

data = read.table("file.csv",sep="\t",header=T,comment.char="")

read.table() 함수의 기본 동작은 comment.char="#"이다. comment.char에 지정할 수 있는 값은 당연히 단일 문자여야 한다. ""를 지정하면 모든 라인을 주석으로 해석하지 않는다. 읽어들인 파일이 데이터프레임으로 잘 전환되었는지를 확인해 보자.


왜 첫번째 컬럼의 이름이 X.Genus인가? 원본 파일의 값은 #Genus인데 특수문자가 있어서 이를 그대로 컬럼 이름으로 쓰기에 곤란하기 때문이다. 원본 파일의 #Genus를 AGenus, 1Genus, _Genus, 등으로 바꾸어 보면서 R이 이를 어떻게 적절히 컬럼 이름으로 변환하는지를 확인해 보라.

read.csv() 함수는 comment.char=""임을 기억해 두자. 주석이 없는 순수한 데이터값으로만 이루어진 파일을 읽어들이는 상황이 대부분일 것이라고 가정하여 동작한다는 의미가 아니겠는가?

함수의 용법을 정확히 하는 것 못지않게 데이터 파일을 텍스트 편집기로 한번쯤은 열어서 훑어보면서 헤더는 어떻게 구성되어 있는지, 중간에 주석줄은 없는지 등을 확인해 보는 것이 현명할 것이다.

댓글 없음: