1. Read tabular data into R

read.table() : 테이블 포맷으로 되어 있는 파일을 읽어 데이터프레임을 반환한다.

  • usage: read.table(file, header = FALSE, sep = “”)
  • parameter:
    • 파일의 맨 위에 열의 이름을 부여하는 ‘헤더라인’ 을 포함하는 경우, header = TRUE 를 지정하면 데이터프레임을 만들때 열 이름을 붙여준다.
    • 이 함수는 데이터 필드가 빈 칸 (공백이나 탭) 으로 구분될 것이라고 자동으로 가정한다는 특징이 있으므로, 빈칸 대신 다른 구분자를 사용하는 파일이라면 sep 파라미터로 지정한다. (예) sep = “:”
    • 이 함수는 기본으로 문자열 등 비수치형 데이터를 요인(Factor)으로 해석한다. 문자열을 요인으로 해석하지 못하게 하려면 stringAsFactors = FALSE 로 지정하면 된다.
    • R 에서 true, false 논리연산자는 대문자 TRUE/FALSE 혹은 T/F 로 표시함

read.csv(): 값이 comma 로 구분되어 있는 파일(“.csv”)을 읽어 데이터프레임을 반환한다.

  • csv : comma-separated value 의 약자
  • csv 파일 형식은 엑셀 등 스프레드시트 프로그램, 데이터베이스 관리자 및 대부분의 통계 패키지들이 데이터를 가져오고 내보낼 수 있는 형식이기 때문에 널리 쓰이고 있다.
  • usage: read.csv(file, header = TRUE, sep = “,”)
  • parameter : read.table 과 동일

(1) 파일 불러오기

# Read tabular data into R as a dataframe 
commute <- read.table("data/commute.txt", header = TRUE, sep = "\t", stringsAsFactors = F)
# 첫 6행 읽기
head(commute)  
##         Date Day Depart Arrive
## 1 2010-06-15   T   5:37   6:05
## 2 2010-06-16   W   5:08   5:35
## 3 2010-06-17   H   4:58   5:17
## 4 2010-06-18   F   5:01   5:17
## 5 2010-06-21   M   5:17   5:41
## 6 2010-06-25   F   5:21   5:38

요일별 출근소요시간을 파악해보자. 이 과정에서 데이터 자료형 변환과 날짜시간 자료형에 대해 함께 살펴보기로 한다.

(2) 데이터 자료형 변환 및 연산

  • 파일에서 읽어들인 데이터프레임의 자료구조를 확인한 후 필요한 형태로 변환한다.
  • 자료형을 변환하려면 as.‘자료형’( ) 함수를 사용한다.
    • 예: as.character(), as.factor(), as.numeric(), as.integer()
# commute data frame 구조 확인
str(commute)  
## 'data.frame':    63 obs. of  4 variables:
##  $ Date  : chr  "2010-06-15" "2010-06-16" "2010-06-17" "2010-06-18" ...
##  $ Day   : chr  "T" "W" "H" "F" ...
##  $ Depart: chr  "5:37" "5:08" "4:58" "5:01" ...
##  $ Arrive: chr  "6:05" "5:35" "5:17" "5:17" ...
  • 변수들은 모두 문자열 자료형(chr)으로 되어 있다.
  • 시계열 데이터를 다룰 때 변수를 날짜 타입으로 변환하면 활용에 편리한 점이 많다.
  • R의 날짜 자료형으로는 “Date” 객체 이외에 “POSIXct”, “POSIXlt” 등이 있으며, as.POSIXct 함수를 통해 문자 변수를 변환할 수 있다.
# Date 와 Depart, Date 와 Arrive 컬럼을 각각 합쳐서 POSIXct 형으로 변환
Dep <- as.POSIXct(paste(commute$Date, commute$Depart))  # paste() : 문자열 합치기
Arr <- as.POSIXct(paste(commute$Date, commute$Arrive))
# POSIXct 형으로 변환한 이후에는 기본 연산으로 시간차이를 계산할 수 있음
Arr - Dep
## Time differences in mins
##  [1] 28 27 19 16 24 17 21 21 17 17 19 21 23 17 18 27 17 20 21 21 22 34 29
## [24] 29 26 22 29 28 16 19 36 27 21 22 22 19 12 21 25 27 23 19 20 29 27 26
## [47] 23 28 19 15 21 21 23 28 21 18 19 32 18 18 25 19 21
# 시간차이 계산한 것을 Diff 변수에 할당
Diff <- Arr - Dep
# commute 데이터프레임에 Diff 변수 합치기
new_commute <- cbind(commute, Diff)  # cbind : column 기준으로 합치기
head(new_commute)
##         Date Day Depart Arrive    Diff
## 1 2010-06-15   T   5:37   6:05 28 mins
## 2 2010-06-16   W   5:08   5:35 27 mins
## 3 2010-06-17   H   4:58   5:17 19 mins
## 4 2010-06-18   F   5:01   5:17 16 mins
## 5 2010-06-21   M   5:17   5:41 24 mins
## 6 2010-06-25   F   5:21   5:38 17 mins

(3) 요일별 출근시간 비교 시각화

“difftime” 자료형으로 생성된 Diff 컬럼을 다시 숫자형으로 변경하여 Boxplot 그래프를 그린다.

# new_commute$Diff 의 데이터타입 확인 : difftime class 는 그래프를 그릴 수 없음
class(new_commute$Diff)
## [1] "difftime"
# Diff 벡터를 숫자형으로 변환하여 new_commute 데이터프레임에 열 추가
Diff <- as.numeric(Diff)
new_commute <- cbind(commute, Diff) 
str(new_commute)
## 'data.frame':    63 obs. of  5 variables:
##  $ Date  : chr  "2010-06-15" "2010-06-16" "2010-06-17" "2010-06-18" ...
##  $ Day   : chr  "T" "W" "H" "F" ...
##  $ Depart: chr  "5:37" "5:08" "4:58" "5:01" ...
##  $ Arrive: chr  "6:05" "5:35" "5:17" "5:17" ...
##  $ Diff  : num  28 27 19 16 24 17 21 21 17 17 ...
# 상자그림 그리기
boxplot(Diff~Day, new_commute)

  • 기본옵션으로 요일(x축)의 알파벳 순으로 그래프가 그려짐.
  • 요일순서로 그래프를 그리려면 요일을 요인(factor)으로 변환하고, 요인의 순서(level)를 지정하면 됨
# Day 컬럼의 자료형을 요인으로 바꾸고 레벨의 순서를 지정
new_commute$Day <- factor(new_commute$Day, levels = c("M", "T", "W", "H", "F"))
str(new_commute)
## 'data.frame':    63 obs. of  5 variables:
##  $ Date  : chr  "2010-06-15" "2010-06-16" "2010-06-17" "2010-06-18" ...
##  $ Day   : Factor w/ 5 levels "M","T","W","H",..: 2 3 4 5 1 5 1 4 5 1 ...
##  $ Depart: chr  "5:37" "5:08" "4:58" "5:01" ...
##  $ Arrive: chr  "6:05" "5:35" "5:17" "5:17" ...
##  $ Diff  : num  28 27 19 16 24 17 21 21 17 17 ...
# 상자그림 그리기
boxplot(Diff~Day, new_commute)

전달력을 높이기 위해 M, T, W, H, F 를 Monday, Tuesday… 로 변경함.

levels(new_commute$Day)[levels(new_commute$Day)=="M"] <- "Monday"
levels(new_commute$Day)[levels(new_commute$Day)=="T"] <- "Tuesday"
levels(new_commute$Day)[levels(new_commute$Day)=="W"] <- "Wednesday"
levels(new_commute$Day)[levels(new_commute$Day)=="H"] <- "Thursday"
levels(new_commute$Day)[levels(new_commute$Day)=="F"] <- "Friday"

boxplot(Diff~Day, new_commute)

[Dr.Breheny 의 저녁 출근 소요시간 패턴읽기]

  • 요일별 평균 출근소요시간은 금요일이 가장 짧고 화요일이 가장 길다
  • 금요일은 출근소요시간이 거의 일정하고, 월,화요일은 출근소요시간의 차이가 크다.
  • 목요일은 출근소요시간의 이상치(outlier) 가 존재한다.
  • 요일별로 관측치에 차이가 존재하나? tabel() 함수로 도수분포 확인.
# 도수분포 확인
table(new_commute$Day)
## 
##    Monday   Tuesday Wednesday  Thursday    Friday 
##        15        14        11        12        11

좀더 살펴보기

날짜와 시간을 다루는 클래스

(1) 문자열을 날짜로 변환하기
  • as.Date 함수는 출력을 위해 다시 문자열로 변환되는 Date 객체를 반환한다.
  • as.Date 가 문자열을 해석할 수 있도록 format 인자를 넣어줘야 한다.
    • 기본으로 yyyy-mm-dd 형식일 것이라고 가정하고 변환해줌.
    • mm/dd/yyyy 또는 mm/dd/yy 로 되어 있다면 format = “%m/%d/%Y” 또는 format = “%m/%d/%y” 를 지정해줘야 함 (대문자 Y는 4자리 연도, 소문자 y는 2자리 연도)
as.Date("2018-09-01")
## [1] "2018-09-01"
as.Date("2018/09/01")
## [1] "2018-09-01"
as.Date("09/01/2018") # "0009-01-20" 으로 변환됨
## [1] "0009-01-20"
as.Date("09/01/2018", format = "%m/%d/%Y")
## [1] "2018-09-01"
as.Date("09/01/18", format = "%m/%d/%y" ) 
## [1] "2018-09-01"

그 외의 형식으로 되어 있는 문자열을 날짜로 변환하려면?

  • yyyy, mm, dd로 표현된 날짜 : ISOdaste 함수를 이용
  • ISOdate 함수는 세개의 숫자를 통합해 Date 객체로 변환이 가능한 POSIXct 객체(날짜 및 시간 클래스)로 만듬
  • 순수하게 날짜만 가지고 작업할 때는 Date 객체로 변환해서 쓰이지 않는 시간정보의 길이를 줄임
# ISOdate 함수로 POSIXct 객체로 변환
ISOdate(2018, 9, 1)
## [1] "2018-09-01 12:00:00 GMT"
# Date 객체로 변환
as.Date(ISOdate(2018, 9, 1))
## [1] "2018-09-01"
(2) 시간자료형에서 하위 원소 추출하기
  • Sys.time() 함수를 통해 현재 시스템 시간정보를 받아내면 POSIXct 클래스가 생성된다.

  • 문자열을 받아 as.POSIXlt(), as.POSIXct() 함수를 사용해서 시간자료형으로 변환시킨다. POSIXlt 자료형으로 변환시킨 경우 리스트로 저장되어 있어 시, 분, 초, 요일등 하위 원소값으로 뽑아낼 수 있다.

Sys.Date()  # 현재 날짜를 반환하는 함수
## [1] "2018-08-24"
class(Sys.Date())  # Sys.Date() 함수는 Date 객체를 반환 
## [1] "Date"
as.POSIXlt(Sys.Date())$wday
## [1] 5
Sys.time()  # 현재 날짜시간을 반환하는 함수
## [1] "2018-08-24 22:55:55 KST"
class(Sys.time())  # Sys.time() 함수는 POSIXct 객체를 반환
## [1] "POSIXct" "POSIXt"
names(unclass(as.POSIXlt(Sys.time())))  # unclass로 리스트의 이름을 
##  [1] "sec"    "min"    "hour"   "mday"   "mon"    "year"   "wday"  
##  [8] "yday"   "isdst"  "zone"   "gmtoff"
as.POSIXlt(Sys.time())$mon  # 월 (0-11, 0 = 1월)
## [1] 7
as.POSIXlt(Sys.time())$mday  # 해당 달의 몇번째 날 (1-31)
## [1] 24
as.POSIXlt(Sys.time())$wday  # 해당 주의 몇번째 날 (0=6, 0= 일요일)
## [1] 5
as.POSIXlt(Sys.time())$yday  # 해당 해의 몇번째 날 (0-365, 0 = 1월1일)
## [1] 235
when <- as.Date(ISOdate(2018, 9, 1))
as.POSIXlt(when)$mon  # 월 (0-11, 0 = 1월)
## [1] 8
as.POSIXlt(when)$mday  # 해당 달의 몇번째 날 (1-31)
## [1] 1
as.POSIXlt(when)$wday  # 해당 주의 몇번째 날 (0=6, 0= 일요일)
## [1] 6
as.POSIXlt(when)$yday  # 해당 해의 몇번째 날 (0-365, 0 = 1월1일)
## [1] 243

KST(Korea Standard Time, 한국 표준시) = UTC (Universal Time Coordinated, 세계협정시) +9

Handling date-times in R http://biostat.mc.vanderbilt.edu/wiki/pub/Main/ColeBeck/datestimes.pdf