이번 포스팅에서는 외부 텍스트 파일을 불러오기 할 때에

 

 

Error in scan(file = file, what = what, sep = sep, quote = quote, dec = dec, 

: line 3 did not have 5 elements

 

와 같은

(1) 에러 메시지가 뜨는 이유와

(2) 대처 방안

(3) 유의 사항

 

에 대해서 알아보겠습니다.

 

 

(1) 에러메시지 이유

Error in scan(file = file, what = what, sep = sep, quote = quote, dec = dec, 

: line 3 did not have 5 elements 

 

에러메시지가 뜨는 이유는 3번째 행(line 3)의 원소의 개수가 결측값(missing value) 때문에 총 5개가 안되기 때문입니다. (row name 1개, 행 4개 모두 포함해서 총 5개 원소)

 

아래에 간단한 예를 들어서 설명하겠습니다.

 

cat() 함수를 이용해서 V1, V2, V3, V4 라는 변수명을 가진 4개의 변수에 대해 First, Second, Third, Fourth라는 rowname을 가진 text 파일을 만들어보았습니다. 이때 의도적으로 3번째 행(3rd row, 3 line)에 원소를 row name 포함해서 4개만 만들어보았습니다. (다른 행은 모두 5개 원소, 3행만 4개 원소) 

MyDocument 폴더에 가보면 test.txt 라는 파일이 생성되어 있음을 확인할 수 있으며, 그 파일을 열어보면 아래 화면 캡쳐한 것 처럼 데이터가 들어가 있으며, 3행은 원소가 총 4개이며, 다른 행 대비 1개가 모자람을 알 수 있습니다.  

 

> ##-----------------------------------------------##
> ## Error in scan(file, what, nmax, sep, dec, quote, skip, nlines, na.strings,  
> ## :line 3 did not have 5 elements
> ##-----------------------------------------------##
> 
> # exmaple with missing value in line 3 at 5th element
> cat("V1 V2 V3 V4\nFirst 1 2 3 4\nSecond 5 6 7 8\nThird 9 10 11\nFourth 13 14 15 16", file="test.txt")

 

 

 

 

 

 

 

이렇게 생긴 데이터를 read.table() 함수를 써서 읽어들여보겠습니다.

 

> read.table("test.txt", header = TRUE)
Error in scan(file = file, what = what, sep = sep, quote = quote, dec = dec,  : 
  line 3 did not have 5 elements
In addition: Warning message:
In read.table("test.txt", header = TRUE) :
  'test.txt'에서 readTableHeader에 의하여 발견된 완성되지 않은 마지막 라인입니다

 

 

다른 행은 총 5개의 원소(row name 1개, 변수 4개)가 있는데 반해, 3번째 행은 5개 원소가 아니라는 에러 메시지가 떴습니다.  원소가 일부 모자란다는 뜻입니다.

 

 

 

(2) 대처 방안

첫번째 방법은 파일을 열어서 결측값 위치를 찾아가서 그 값에 제대로 된 값을 채워넣는 것입니다.  파일의 데이터 개수가 몇 개 안되고 육안으로 확인해서 채워넣을 수 있는 경우에는 적용가능 하겠지만, 만약 데이터 개수가 수천, 수만, 수십만 개라면 많이 힘들겠지요? ^^;

 

두번째 방법은, 만약 원소의 개수가 모자라는 이유가 제일 마지막 열에 결측값(missing value)가 있기 때문이라면 fill = TRUE 옵션을 부가하면 NA 표기가 부가되면서 읽어들이기를 간단하게 해결할 수 있습니다.

 

> # missing value => NA : fill = TRUE
> testfile <- read.table("test.txt", header = TRUE, fill = TRUE)
Warning message:
In read.table("test.txt", header = TRUE, fill = TRUE) :
  'test.txt'에서 readTableHeader에 의하여 발견된 완성되지 않은 마지막 라인입니다
> 
> testfile
       V1 V2 V3 V4
First   1  2  3  4
Second  5  6  7  8
Third   9 10 11 NA
Fourth 13 14 15 16

 

 

 

 

(3) 유의사항

 

한가지 주의할 사항이 있는데요, fill = TRUE 옵션은 "결측값이 마지막 행의 값일 경우에만 해당"된다는 점입니다.

 

아래에 예를 하나 들어보았는데요, 1번째 행의 1번째 열값과 3번째 행의 4번째 열값이 결측값인 데이터셋이 있다고 해봅시다.

 

> # matters that require attention : only for the last column's missing value
> cat("V1 V2 V3 V4\nFirst   2 3 4\nSecond 5 6 7 8\nThird 9 10 11\nFourth 13 14 15 16", file="test_2.txt")

 

 

> read.table("test_2.txt", header = TRUE)
Error in scan(file = file, what = what, sep = sep, quote = quote, dec = dec,  : 
  line 1 did not have 5 elements
In addition: Warning message:
In read.table("test_2.txt", header = TRUE) :
  'test_2.txt'에서 readTableHeader에 의하여 발견된 완성되지 않은 마지막 라인입니다
>

 

 

아래처럼 fill = TRUE 옵션을 써서 read.table()로 test_2.txt 파일 데이터 불러오기를 해봤습니다. 

첫번째 행(1st row)을 유심히 보시기 바랍니다.

첫번째 행의 1번째 열 값이 결측치(when value of 1st row and 1st column is missing)인 상황이라고 했는데요, fill = TRUE 옵션으로 해서 불어들였더니 첫번째 행의 4번째 열(1st row and 4th column)에 NA 라고 마킹이 되서 불러오기를 했습니다. 

 

아래 처럼 불러오기를 바랬는데요,

        V1  V2  V3  V4

First  NA   2    3    4

 

실제 R이 fill = TRUE 옵션을 썼을 때 불러온 것은

        V1  V2  V3  V4

First   2    3    4   NA

 

입니다. 

 

다시 한번 유의할 사항을 말씀드리자면, fill = TRUE 옵션은 "행의 마지막 값이 결측치인 경우에만" 사용해야 합니다.

 

> read.table("test_2.txt", header = TRUE, fill = TRUE)
       V1 V2 V3 V4
First   2  3  4 NA
Second  5  6  7  8
Third   9 10 11 NA
Fourth 13 14 15 16
Warning message:
In read.table("test_2.txt", header = TRUE, fill = TRUE) :
'test_2.txt'에서 readTableHeader에 의하여 발견된 완성되지 않은 마지막 라인입니다 

 

많은 도움 되었기를 바랍니다.

 

Posted by R Friend R_Friend

댓글을 달아 주세요

  1. R Friend R_Friend 2016.06.17 11:26 신고  댓글주소  수정/삭제  댓글쓰기

    DB에서 데이터 내릴때 구분자(delimeter) 설정 잘 해주는게 중요합니다.