아이티윌_데이터 분석 55기/강의내용 필기_통계 및 분석

#6 6일차 : 외부파일 입출력, DB Connection, 기타 기능

ecosso 2026. 4. 7. 16:21

01. 외부파일 입출력

 -01 read.csv

 -02 read.table

 -03 readLines

 -04 readline

 -05 클립보드 데이터 불러오기

 -06 외부파일로 내려쓰기

 

02. DB Connection

 

03. 연습문제

 

04. 기타 기능

 -01 이전/이후값 가져오기

 -02 순위

 


01. 외부파일 입출력

 -01 read.csv
read.csv(file,                       # 불러올 파일명
              header = TRUE,   # 첫번째 행을 컬럼이름으로 처리여부
              sep = ",",               # 필드구분자
              na.strings = "NA", # 불러올 때 결측치로 처리하고 싶은 문자열 지정 (벡터 전달 가능), 
              nrows = -1,           # 불러올 행의 수 
              skip = 0                # 제외시킬 행의 수(처음부터)
              comment.char = "", 
              stringsAsFactors = FALSE,  # 문자열컬럼 factor화 여부부
              fileEncoding = "",
               ...)

 

# header = T

> read.csv('emp.csv', header=T)
   EMPNO  ENAME       JOB  MGR        HIREDATE  SAL COMM DEPTNO
1   7369  SMITH     CLERK 7902 1980-12-17 0:00  800   NA     20
2   7499  ALLEN  SALESMAN 7698 1981-02-20 0:00 1600  300     30
3   7521   WARD  SALESMAN 7698 1982-02-22 0:00 1250  500     30
4   7566  JONES   MANAGER 7839 1981-04-02 0:00 2975   NA     20
5   7654 MARTIN  SALESMAN 7698 1981-09-28 0:00 1250 1400     30
6   7698  BLAKE   MANAGER 7839 1981-05-01 0:00 2850   NA     30
7   7782  CLARK   MANAGER 7839 1981-06-09 0:00 2450   NA     10
8   7788  SCOTT   ANALYST 7566 1987-04-17 0:00 3000   NA     20
9   7839   KING PRESIDENT   NA 1981-11-17 0:00 5000   NA     10
10  7844 TURNER  SALESMAN 7698 1981-09-08 0:00 1500    0     30
11  7876  ADAMS     CLERK 7788 1987-05-23 0:00 1100   NA     20
12  7900  JAMES     CLERK 7698 1981-12-03 0:00  950   NA     30
13  7902   FORD   ANALYST 7566 1981-12-03 0:00 3000   NA     20
14  7934 MILLER     CLERK 7782 1982-01-23 0:00 1300   NA     10

 

# header = F

> read.csv('emp.csv', header=F)
      V1     V2        V3   V4              V5   V6   V7     V8
1  EMPNO  ENAME       JOB  MGR        HIREDATE  SAL COMM DEPTNO
2   7369  SMITH     CLERK 7902 1980-12-17 0:00  800          20
3   7499  ALLEN  SALESMAN 7698 1981-02-20 0:00 1600  300     30
4   7521   WARD  SALESMAN 7698 1982-02-22 0:00 1250  500     30
5   7566  JONES   MANAGER 7839 1981-04-02 0:00 2975          20
6   7654 MARTIN  SALESMAN 7698 1981-09-28 0:00 1250 1400     30
7   7698  BLAKE   MANAGER 7839 1981-05-01 0:00 2850          30
8   7782  CLARK   MANAGER 7839 1981-06-09 0:00 2450          10
9   7788  SCOTT   ANALYST 7566 1987-04-17 0:00 3000          20
10  7839   KING PRESIDENT      1981-11-17 0:00 5000          10
11  7844 TURNER  SALESMAN 7698 1981-09-08 0:00 1500    0     30
12  7876  ADAMS     CLERK 7788 1987-05-23 0:00 1100          20
13  7900  JAMES     CLERK 7698 1981-12-03 0:00  950          30
14  7902   FORD   ANALYST 7566 1981-12-03 0:00 3000          20
15  7934 MILLER     CLERK 7782 1982-01-23 0:00 1300          10

 

# norws = 5

> read.csv('emp.csv', nrows = 5)
  EMPNO  ENAME      JOB  MGR        HIREDATE  SAL COMM DEPTNO
1  7369  SMITH    CLERK 7902 1980-12-17 0:00  800   NA     20
2  7499  ALLEN SALESMAN 7698 1981-02-20 0:00 1600  300     30
3  7521   WARD SALESMAN 7698 1982-02-22 0:00 1250  500     30
4  7566  JONES  MANAGER 7839 1981-04-02 0:00 2975   NA     20
5  7654 MARTIN SALESMAN 7698 1981-09-28 0:00 1250 1400     30

 

# skip = 5

> read.csv('emp.csv', skip = 5)
  X7654 MARTIN  SALESMAN X7698 X1981.09.28.0.00 X1250 X1400 X30
1  7698  BLAKE   MANAGER  7839  1981-05-01 0:00  2850    NA  30
2  7782  CLARK   MANAGER  7839  1981-06-09 0:00  2450    NA  10
3  7788  SCOTT   ANALYST  7566  1987-04-17 0:00  3000    NA  20
4  7839   KING PRESIDENT    NA  1981-11-17 0:00  5000    NA  10
5  7844 TURNER  SALESMAN  7698  1981-09-08 0:00  1500     0  30
6  7876  ADAMS     CLERK  7788  1987-05-23 0:00  1100    NA  20
7  7900  JAMES     CLERK  7698  1981-12-03 0:00   950    NA  30
8  7902   FORD   ANALYST  7566  1981-12-03 0:00  3000    NA  20
9  7934 MILLER     CLERK  7782  1982-01-23 0:00  1300    NA  10

 

# skip = 5, header = F

> read.csv('emp.csv', skip = 5, header = F)
     V1     V2        V3   V4              V5   V6   V7 V8
1  7654 MARTIN  SALESMAN 7698 1981-09-28 0:00 1250 1400 30
2  7698  BLAKE   MANAGER 7839 1981-05-01 0:00 2850   NA 30
3  7782  CLARK   MANAGER 7839 1981-06-09 0:00 2450   NA 10
4  7788  SCOTT   ANALYST 7566 1987-04-17 0:00 3000   NA 20
5  7839   KING PRESIDENT   NA 1981-11-17 0:00 5000   NA 10
6  7844 TURNER  SALESMAN 7698 1981-09-08 0:00 1500    0 30
7  7876  ADAMS     CLERK 7788 1987-05-23 0:00 1100   NA 20
8  7900  JAMES     CLERK 7698 1981-12-03 0:00  950   NA 30
9  7902   FORD   ANALYST 7566 1981-12-03 0:00 3000   NA 20
10 7934 MILLER     CLERK 7782 1982-01-23 0:00 1300   NA 10

 


# 공백으로 구분된 a1.txt 파일 불러오기

# header = F

> read.csv('a1.txt', header = F)
              V1
1 1.00 2.00 3.00
2 4.00 5.00 6.00

 

# header = F, sep = " " 

> read.csv('a1.txt', header = F, sep = "")
  V1 V2 V3
1  1  2  3
2  4  5  6

 

# read.table로 불러오기

> read.table('a1.txt')
  V1 V2 V3
1  1  2  3
2  4  5  6

 -02 read.table

read.table(file, 
           header = FALSE, 
           sep = "",       # 필드구분자(한칸공백 이상 분리)
           row.names, 
           col.names, 
           na.strings = "NA", 
           nrows = -1,
           skip = 0, 
           stringsAsFactors = FALSE,
           fileEncoding = "", )


 -03 readLines

> readLines('file1.txt')
[1] "1,2,3" "4,5,6"
경고메시지(들):
readLines("file1.txt")에서:
  'file1.txt'에서 불완전한 마지막 행이 발견되었습니다

 

 * R에서 불러올 때 마지막 경계가 불확실한 경우 해당 경고메시지가 발생한다.

 

# ** readLines로 한글파일 불러오기(불러온 뒤 따로 변환 필요)

> lines <- readLines("seoul_new.txt")
> lines <- iconv(lines, from = "CP949", to = "UTF-8")
> lines
  [1] "305 무료법률상담에 대한 부탁의 말씀 입니다. 2017-09-27 2 "                   
  [2] "304 [교통불편접수] 6715 버스(신월동->상암동) 2017-09-26 2 "                  
  [3] "303 경기도 시흥시 아파트 화재~ 2017-09-22 145 "                              
  [4] "302 마곡지구 하자보수 관련 2017-09-22 57 "                                   
  [5] "301 가깝고도 먼 강남(성수동에서 압구정역 방면) 2017-09-22 83 "               
  [6] "300 청담나들목(제외지측)입구 주변지역안내도 정비 필요 2017-09-22 20 "        
  [7] "299 전 제주도 시민입니다만.. 2017-09-16 2 "                                  
  [8] "298 지방자치제 실시로 소요되는 비용 2017-09-16 0 "                           
  [9] "297 평생 살던 삶의 터전인 주택을 빼앗기게 생겼습니다ㅠ 2017-09-15 5 "        
 [10] "296 불법확장노점상 이전 및 원상복구 시장님께 강력 요청 2017-09-15 1 " 

 

 ** 텍스트 파일을 read.csv를 이용하여 불러오는 경우 sep 옵션을 '\n' 로 사용한다.

> read.csv('seoul_new.txt', header = F, sep = '\n', fileEncoding =  'cp949')
                                                                              V1
1                      305 무료법률상담에 대한 부탁의 말씀 입니다. 2017-09-27 2 
2                     304 [교통불편접수] 6715 버스(신월동->상암동) 2017-09-26 2 
3                                 303 경기도 시흥시 아파트 화재~ 2017-09-22 145 
4                                      302 마곡지구 하자보수 관련 2017-09-22 57 
5                  301 가깝고도 먼 강남(성수동에서 압구정역 방면) 2017-09-22 83 
6           300 청담나들목(제외지측)입구 주변지역안내도 정비 필요 2017-09-22 20 
7                                     299 전 제주도 시민입니다만.. 2017-09-16 2 
8                              298 지방자치제 실시로 소요되는 비용 2017-09-16 0 
9           297 평생 살던 삶의 터전인 주택을 빼앗기게 생겼습니다ㅠ 2017-09-15 5 
10          296 불법확장노점상 이전 및 원상복구 시장님께 강력 요청 2017-09-15 1 

 -04 readline

사용자에게 입력값을 유도한다.

> readline('2026/04/07 데이터를 크롤링할까요? (Y|N)')
2026/04/07 데이터를 크롤링할까요? (Y|N)y
[1] "y"

 

> ans <- readline('2026/04/07 데이터를 크롤링할까요? (Y|N)')
2026/04/07 데이터를 크롤링할까요? (Y|N) N
> if ( ans == 'Y') {
+    print('크롤링 코드 ...')
+ } else {
+    print ('프로그램 중단 코드 ...')
+   }
[1] "프로그램 중단 코드 ..."

 -05 클립보드 데이터 불러오기

클립보드상에 존재하는 데이터를 불러온다.

> read.table('clipboard')
                                                                                                        V1
1 연령별,2000년,2001년,2002년,2003년,2004년,2005년,2006년,2007년,2008년,2009년,2010년,2011년,2012년,2013년
2                                               20대,7.5,7.4,6.6,7.7,7.9,7.7,7.7,7.1,7,7.9,7.8,7.4,7.5,7.9
3                                                     30대,3.6,3.2,2.9,3,3.1,3.3,3,3.2,3.1,3.6,3.5,3.4,3,3
4                                                     40대,3.5,3,2,2.2,2.3,2.6,2.3,2,2.1,2.5,2.5,2.1,2.1,2
5                                                 50대,3.3,2.8,2,2.2,2.3,2.5,2.2,2.1,2,2.5,2.4,2.1,2.1,1.9
6                                             60세이상,1.5,1.2,1.1,1,1.2,1.3,1.4,1.4,1.2,1.6,3,2.7,2.5,1.9

 

> read.table('clipboard', header = T, sep = ',')
    연령별 X2000년 X2001년 X2002년 X2003년 X2004년 X2005년 X2006년 X2007년 X2008년 X2009년
1     20대     7.5     7.4     6.6     7.7     7.9     7.7     7.7     7.1     7.0     7.9
2     30대     3.6     3.2     2.9     3.0     3.1     3.3     3.0     3.2     3.1     3.6
3     40대     3.5     3.0     2.0     2.2     2.3     2.6     2.3     2.0     2.1     2.5
4     50대     3.3     2.8     2.0     2.2     2.3     2.5     2.2     2.1     2.0     2.5
5 60세이상     1.5     1.2     1.1     1.0     1.2     1.3     1.4     1.4     1.2     1.6
  X2010년 X2011년 X2012년 X2013년
1     7.8     7.4     7.5     7.9
2     3.5     3.4     3.0     3.0
3     2.5     2.1     2.1     2.0
4     2.4     2.1     2.1     1.9
5     3.0     2.7     2.5     1.9

 

# 테이블로 저장하기

> df1 <- read.table('clipboard', header = T, sep = ',')
> df1
    연령별 X2000년 X2001년 X2002년 X2003년 X2004년 X2005년 X2006년 X2007년 X2008년 X2009년
1     20대     7.5     7.4     6.6     7.7     7.9     7.7     7.7     7.1     7.0     7.9
2     30대     3.6     3.2     2.9     3.0     3.1     3.3     3.0     3.2     3.1     3.6
3     40대     3.5     3.0     2.0     2.2     2.3     2.6     2.3     2.0     2.1     2.5
4     50대     3.3     2.8     2.0     2.2     2.3     2.5     2.2     2.1     2.0     2.5
5 60세이상     1.5     1.2     1.1     1.0     1.2     1.3     1.4     1.4     1.2     1.6
  X2010년 X2011년 X2012년 X2013년
1     7.8     7.4     7.5     7.9
2     3.5     3.4     3.0     3.0
3     2.5     2.1     2.1     2.0
4     2.4     2.1     2.1     1.9
5     3.0     2.7     2.5     1.9

 


 -06 외부파일로 내려쓰기

write.csv(x,           # 저장할 데이터프레임
              file = ,     # 파일명
              sep = " " ,  # 필드구분자 (defalut는 " ")
              row.names = T, # 행이름 저장 여부
              col.names = T  # 컬럼이름 저장 여부
              fileEncoding = ) 

 

> df1 <- data.frame(name = c('smith', 'allen', 'scott'),
+                   sal = c(800, 900, 1000))
> write.csv(df1, 'df1.csv')

 

 

 

# 행 이름 없이 저장하기

> write.csv(df1, 'df1.csv', row.names = F)

 

 


2. DB Connection


 1. target DB 필요
 ** 접속 정보
 IP : localhost
 PORT : 1521(11g)
 SID : orcl

 cmd에서 확인(port, sid) 가능
 lsnrctl satatus

 

 

2. R에서 드라이버 설치(RJDBC) 및 실행
install.packages('RJDBC')
library(RJDBC)

 

3. R <-> Oracle 통신 세팅 (ojdbc.jar)
   64bit   32bit  호환 이슈 발생!
    -> oracle 11g 64bit client 설치 필요

 ** oracle install 유형
 1) server : 자체 DB 생성 가능
 2) client : 자체 DB 생성 불가, 다른 DB와의 통신만 가능

 

jdbcdriver <- JDBC(driverClass = 'oracle.jdbc.OracleDriver',                       # driver 이름
                                classPath = 'D:/경로/ojdbc6.jar') # driver 위치

con1 <- dbConnect(jdbcdriver,                                               # driver 정보
                               'jdbc:oracle:thin:@localhost:1521:orcl',  # DB 정보
                               'scott',                                                      # userid
                               'oracle')                                                    # passwd

 

dbGetQuery(conn = ,                # connection 이름
                     statement = )        # sql문

> dbGetQuery(con1, 'select * from emp')
   EMPNO  ENAME       JOB  MGR   HIREDATE  SAL COMM DEPTNO
1   7369  SMITH     CLERK 7902 1980-12-17  800   NA     40
2   7499  ALLEN  SALESMAN 7698 1981-02-20 1600  300     30
3   7521   WARD  SALESMAN 7698 1981-02-22 1250  500     30
4   7566  JONES   MANAGER 7839 1981-04-02 2975   NA     20
5   7654 MARTIN  SALESMAN 7698 1981-09-28 1250 1400     30
6   7698  BLAKE   MANAGER 7839 1981-05-01 2850   NA     30
7   7782  CLARK   MANAGER 7839 1981-06-09 2450   NA     10
8   7788  SCOTT   ANALYST 7566 1987-04-19 3000   NA     20
9   7839   KING PRESIDENT   NA 1981-11-17 5000   NA     10
10  7844 TURNER  SALESMAN 7698 1981-09-08 1500    0     30
11  7876  ADAMS     CLERK 7788 1987-05-23 1100   NA     20
12  7900  JAMES     CLERK 7698 1981-12-03  950   NA     30
13  7902   FORD   ANALYST 7566 1981-12-03 3000   NA     20
14  7934 MILLER     CLERK 7782 1982-01-23 1300   NA     10

 

> dbGetQuery(con1, 'select * from emp2')
      EMPNO   NAME   BIRTHDAY DEPTNO EMP_TYPE          TEL      HOBBY     PAY POSITION   PEMPNO
1  19900101 나사장 1964-01-25   0001   정규직 054)223-0001   음악감상 1.0e+08 대표이사       NA
2  19960101 전부장 1973-03-22   1000   정규직 02)6255-8000       독서 7.2e+07     부장 19900101
3  19970201 최일도 1975-04-15   1000   정규직 02)6255-8005       운동 5.0e+07     과장 19960101
4  19930331 백원만 1976-05-25   1001   정규직 02)6255-8010 자전거타기 6.0e+07     차장 19960101
5  19950303 천만득 1973-06-15   1002   정규직 02)6255-8020     마라톤 5.6e+07     과장 19960101
6  19966102 일지매 1972-07-05   1003   정규직 052)223-4000   음악감상 7.5e+07     부장 19900101
7  19930402 유관순 1972-08-15   1004   정규직 042)998-7005       등산 5.1e+07     과장 19966102
8  19960303 김문호 1971-09-25   1005   정규직 031)564-3340       등산 3.5e+07     대리 19966102
9  19970112 노정호 1976-11-05   1006   정규직 054)223-4500       수영 6.8e+07     부장 19900101
10 19960212 이윤나 1972-12-15   1007   정규직 054)223-4600       <NA> 4.9e+07     과장 19970112
11 20000101 이태백 1985-01-25   1008   계약직 051)123-4567       등산 3.0e+07     <NA> 19960212
12 20000102 김설악 1983-03-22   1009   계약직 031)234-5678       낚시 3.0e+07     <NA> 19960212
13 20000203 최오대 1982-04-15   1010   계약직 02)2345-6789       바둑 3.0e+07     <NA> 19960212
14 20000334 박지리 1981-05-25   1011   계약직 053)456-7890       노래 3.0e+07     <NA> 19960212
15 20000305 정북악 1980-06-15   1008   수습직 051)567-8901       독서 2.2e+07     <NA> 19960212
16 20006106 유도봉 1980-07-05   1009   수습직 031)678-9012         술 2.2e+07     <NA> 19960212
17 20000407 윤주왕 1980-08-15   1010   수습직 02)2789-0123       오락 2.2e+07     <NA> 19960212
18 20000308 강월악 1980-09-25   1011   인턴직 053)890-1234       골프 2.0e+07     <NA> 19960212
19 20000119 장금강 1980-11-05   1004   인턴직 042)901-2345         술 2.0e+07     <NA> 19930402
20 20000210 나한라 1980-12-15   1005   인턴직 031)345-3456       독서 2.0e+07     <NA> 19960303

 

> dbGetQuery(con1, 'select * from emp2, dept2 where emp2.deptno = dept2.dcode')
      EMPNO   NAME   BIRTHDAY DEPTNO EMP_TYPE          TEL      HOBBY     PAY POSITION   PEMPNO
1  19900101 나사장 1964-01-25   0001   정규직 054)223-0001   음악감상 1.0e+08 대표이사       NA
2  19960101 전부장 1973-03-22   1000   정규직 02)6255-8000       독서 7.2e+07     부장 19900101
3  19970201 최일도 1975-04-15   1000   정규직 02)6255-8005       운동 5.0e+07     과장 19960101
4  19930331 백원만 1976-05-25   1001   정규직 02)6255-8010 자전거타기 6.0e+07     차장 19960101
5  19950303 천만득 1973-06-15   1002   정규직 02)6255-8020     마라톤 5.6e+07     과장 19960101
6  19966102 일지매 1972-07-05   1003   정규직 052)223-4000   음악감상 7.5e+07     부장 19900101
7  19930402 유관순 1972-08-15   1004   정규직 042)998-7005       등산 5.1e+07     과장 19966102
8  19960303 김문호 1971-09-25   1005   정규직 031)564-3340       등산 3.5e+07     대리 19966102
9  19970112 노정호 1976-11-05   1006   정규직 054)223-4500       수영 6.8e+07     부장 19900101
10 19960212 이윤나 1972-12-15   1007   정규직 054)223-4600       <NA> 4.9e+07     과장 19970112
11 20000101 이태백 1985-01-25   1008   계약직 051)123-4567       등산 3.0e+07     <NA> 19960212
12 20000102 김설악 1983-03-22   1009   계약직 031)234-5678       낚시 3.0e+07     <NA> 19960212
13 20000203 최오대 1982-04-15   1010   계약직 02)2345-6789       바둑 3.0e+07     <NA> 19960212
14 20000334 박지리 1981-05-25   1011   계약직 053)456-7890       노래 3.0e+07     <NA> 19960212
15 20000305 정북악 1980-06-15   1008   수습직 051)567-8901       독서 2.2e+07     <NA> 19960212
16 20006106 유도봉 1980-07-05   1009   수습직 031)678-9012         술 2.2e+07     <NA> 19960212
17 20000407 윤주왕 1980-08-15   1010   수습직 02)2789-0123       오락 2.2e+07     <NA> 19960212
18 20000308 강월악 1980-09-25   1011   인턴직 053)890-1234       골프 2.0e+07     <NA> 19960212
19 20000119 장금강 1980-11-05   1004   인턴직 042)901-2345         술 2.0e+07     <NA> 19930402
20 20000210 나한라 1980-12-15   1005   인턴직 031)345-3456       독서 2.0e+07     <NA> 19960303
   DCODE      DNAME PDEPT     AREA
1   0001     사장실  <NA> 포항본사
2   1000 경영지원부  0001 서울지사
3   1000 경영지원부  0001 서울지사
4   1001 재무관리팀  1000 서울지사
5   1002     총무팀  1000 서울지사
6   1003     기술부  0001 포항본사
7   1004    H/W지원  1003 대전지사
8   1005    S/W지원  1003 경기지사
9   1006     영업부  0001 포항본사
10  1007 영업기획팀  1006 포항본사
11  1008    영업1팀  1007 부산지사
12  1009    영업2팀  1007 경기지사
13  1010    영업3팀  1007 서울지사
14  1011    영업4팀  1007 울산지사
15  1008    영업1팀  1007 부산지사
16  1009    영업2팀  1007 경기지사
17  1010    영업3팀  1007 서울지사
18  1011    영업4팀  1007 울산지사
19  1004    H/W지원  1003 대전지사
20  1005    S/W지원  1003 경기지사

 

# 다른 DB에 접속하기

con2 <- dbConnect(jdbcdriver,                                # driver 정보
                               'jdbc:oracle:thin:@IP주소:1521:orcl',  # DB 정보
                               'scott',                                       # userid
                               'oracle')                                    # passwd

> dbGetQuery(con2, 'select * from r_test')
  NO                  NAME
1  1 ADsP 시험 일정 : 5/17
2  2 SQLD 시험 일정 : 5/31

03. 연습문제

 

# 1. seoul_new.txt 파일을 불러온 뒤 정형데이터로 변환
# id   title    rdate   cnt
# 305   ...  2017-09-27  2

 

# 풀이1)  각각 추출

> head(df1)
                                                                    V1
1            305 무료법률상담에 대한 부탁의 말씀 입니다. 2017-09-27 2 
2           304 [교통불편접수] 6715 버스(신월동->상암동) 2017-09-26 2 
3                       303 경기도 시흥시 아파트 화재~ 2017-09-22 145 
4                            302 마곡지구 하자보수 관련 2017-09-22 57 
5        301 가깝고도 먼 강남(성수동에서 압구정역 방면) 2017-09-22 83 
6 300 청담나들목(제외지측)입구 주변지역안내도 정비 필요 2017-09-22 20 

 

> vid <- str_extract(df1$V1, '^\\d+')
> vdate <- str_extract(df1$V1, '\\d+-\\d+-\\d+')
> vcnt <- as.numeric(str_extract(df1$V1, '\\d+ $'))
> vtitle <- str_remove_all(df1$V1, '(^\\d+)|(\\d+-\\d+-\\d+)|(\\d+ $)')
> data.frame(id = vid, title = vtitle, rdate = vdate, cnt = vcnt )
     id                                                      title      rdate cnt
1   305                  무료법률상담에 대한 부탁의 말씀 입니다.   2017-09-27   2
2   304                 [교통불편접수] 6715 버스(신월동->상암동)   2017-09-26   2
3   303                               경기도 시흥시 아파트 화재~   2017-09-22 145
4   302                                   마곡지구 하자보수 관련   2017-09-22  57
5   301               가깝고도 먼 강남(성수동에서 압구정역 방면)   2017-09-22  83
6   300        청담나들목(제외지측)입구 주변지역안내도 정비 필요   2017-09-22  20
7   299                                 전 제주도 시민입니다만..   2017-09-16   2
8   298                          지방자치제 실시로 소요되는 비용   2017-09-16   0
9   297       평생 살던 삶의 터전인 주택을 빼앗기게 생겼습니다ㅠ   2017-09-15   5
10  296       불법확장노점상 이전 및 원상복구 시장님께 강력 요청   2017-09-15   1

 

# 풀이2) 그룹지정 후 전체 추출***

> seoul_new2 <- as.data.frame(str_match(df1$V1, '(^\\d+) (.+) (\\d+-\\d+-\\d+) (\\d+) $')[,-1])
> colnames(seoul_new2) <- c('id','title','rdate','cnt')
> seoul_new2
     id                                                   title      rdate cnt
1   305                 무료법률상담에 대한 부탁의 말씀 입니다. 2017-09-27   2
2   304                [교통불편접수] 6715 버스(신월동->상암동) 2017-09-26   2
3   303                              경기도 시흥시 아파트 화재~ 2017-09-22 145
4   302                                  마곡지구 하자보수 관련 2017-09-22  57
5   301              가깝고도 먼 강남(성수동에서 압구정역 방면) 2017-09-22  83
6   300       청담나들목(제외지측)입구 주변지역안내도 정비 필요 2017-09-22  20
7   299                                전 제주도 시민입니다만.. 2017-09-16   2
8   298                         지방자치제 실시로 소요되는 비용 2017-09-16   0
9   297      평생 살던 삶의 터전인 주택을 빼앗기게 생겼습니다ㅠ 2017-09-15   5
10  296      불법확장노점상 이전 및 원상복구 시장님께 강력 요청 2017-09-15   1

# 2. oracle_alert_testdb.log 파일을 불러온뒤 아래 형태와 같은 오라클 오류 데이터만
# 정형 데이터 형태로 변환

> df2
                                                                                                                              Tue.Oct.30.17.43.46.2012
1                                                                                                                    Starting ORACLE instance (normal)
2                                                                                                                              LICENSE_MAX_SESSION = 0
3                                                                                                                         LICENSE_SESSIONS_WARNING = 0
4                                                                                                Shared memory segment for instance monitoring created
5                                                                                                                       Picked latch-free SCN scheme 2
6                                                                        Using LOG_ARCHIVE_DEST_1 parameter default value as USE_DB_RECOVERY_FILE_DEST
7                                                                                                            Autotune of undo retention is turned on. 
8                                                                                                                                             IMODE=BR
9                                                                                                                                             ILAT =27
10                                                                                                                               LICENSE_MAX_USERS = 0


# <ORACLE ERROR TEXT>
# ORA-1109 signalled during: ALTER DATABASE CLOSE NORMAL...

# <변환후>
# CODE  ERROR_MESSAGE
# 1109  signalled during: ALTER DATABASE CLOSE NORMAL... 

 

> df2<- read.csv('oracle_alert_testdb.log', sep = '\n', header = F)
> df2_error <- df2[str_detect(df2$V1, 'ORA-\\d+'), 'V1']
> df_error <- as.data.frame(str_match(df2_error, 'ORA-(\\d+):? (.+)')[,-1])
> df_error
       V1                                                                    V2
1    1109                      signalled during: ALTER DATABASE CLOSE NORMAL...
2   00313                    open failed for members of log group 1 of thread 1
3   00312        online log 1 thread 1: '/app/oracle/oradata/testdb/redo01.log'
4   27037                                          unable to obtain file status
5   00313                    open failed for members of log group 1 of thread 1
6   00312        online log 1 thread 1: '/app/oracle/oradata/testdb/redo01.log'
7   27037                                          unable to obtain file status
8   00313                    open failed for members of log group 1 of thread 1
9   00312        online log 1 thread 1: '/app/oracle/oradata/testdb/redo01.log'
10  27037                                          unable to obtain file status

04. 기타 기능

 -01 이전/이후값 가져오기

v1 <- 1:10

# 1. for문으로 직접 만들기
res <- c()
for (i in 1:length(v1)) {
  if ( i == 1) {
    res <- c(res, NA)
  } else {
    res <- c(res, v1[i-1])
  } 
}

 

res

> res
 [1] NA  1  2  3  4  5  6  7  8  9

 

# 2. data.table
install.packages('data.table')
library(data.table)

data.table::shift(x,            # 벡터
                  n = 1,        # 위치
                  fill = ,      # 가져올 값이 없는 경우 채울 값
                  type = 'lag') # 방향

shift(v1)

> shift(v1)
 [1] NA  1  2  3  4  5  6  7  8  9


shift(v1, fill = 0)
shift(v1, n = 2 , fill = 0)
shift(v1, type = 'lead')

> shift(v1)
 [1] NA  1  2  3  4  5  6  7  8  9
> shift(v1, fill = 0)
 [1] 0 1 2 3 4 5 6 7 8 9
> shift(v1, n=2 , fill=0)
 [1] 0 0 1 2 3 4 5 6 7 8
> shift(v1, type = 'lead')
 [1]  2  3  4  5  6  7  8  9 10 NA

 

# 3. zoo
install.packages('zoo')
library(zoo)
na.locf(object = , # 대상
        na.rm = T, # NA 제거 여부
        fromLast)  # TRUE 설정 시 이후값 가져오기
na.locf(v2)

# 예제) subway2.csv 파일에서 아래 형태로 변경
sub <- read.csv('subway2.csv', fileEncoding = 'cp949', skip = 1)

head(sub)

names(sub)
names(sub) <- str_remove_all(names(sub), '(^X0)|(^X)|(\\.\\d+)')
sub$전체[sub$구분 == '하차'] <- NA

na.locf(sub)

> names(sub) <- str_remove_all(names(sub), '(^X0)|(^X)|(\\.\\d+)')
> sub$전체[sub$구분 == '하차'] <- NA
> na.locf(sub)
        전체 구분     5     6      7      8      9    10    11
1  서울역(1) 승차 17465 18434  50313  93398  78705 86342 93585
2  서울역(1) 하차  7829 48553 110250 233852 121983 79628 75577
3   시 청(1) 승차  2993  4473   7633  10404  13328 16953 25467
4   시 청(1) 하차  4142 19730  67995 175458  83777 48363 47519
5      종 각 승차  7371  7836  14545  24578  23691 32290 47470
6      종 각 하차  4861 29757  93579 245221 153933 88680 83402
7   종로3(1) 승차  7683  6733  11103  20647  20878 32775 46390
8   종로3(1) 하차  2119 18872  34622 103951 110831 95839 93370
9    종로5가 승차  3159  4416   8070  12328  16909 24445 34454
10   종로5가 하차  2977 14274  51907 127936  93821 67136 63338

 

###### 문제풀이
na.locf(sub$전체)

sub$전체[sub$전체 == ""] <- NA
sub$전체 <- na.locf(sub$전체)

names(sub)[-c(1,2)] <- as.numeric(str_sub(names(sub)[-c(1,2)],2,3))

sub


 -02 순위

rank(x,                                   # 벡터(기본순서 : 오름차순 정렬, -를 사용하여 내림차순 정렬)
        na.last = T,                    # NA 마지막 배치여부
        ties.method = c('average',
                                  'first',
                                  'last',
                                  'random',
                                  'max'))

vscore <- c(100,90,90,80,70,60)
rank(vscore) # 값이 작은 순서대로 순위 부여 (6.0 4.5 4.5 3.0 2.0 1.0)
rank(-vscore) # 값이 큰 순서대로 순위 부여 (1.0 2.5 2.5 4.0 5.0 6.0)

> vscore
[1] 100  90  90  80  70  60
> rank(vscore)
[1] 6.0 4.5 4.5 3.0 2.0 1.0
> rank(-vscore)
[1] 1.0 2.5 2.5 4.0 5.0 6.0

 

rank(-vscore, ties.method = 'first') # 동순위를 인정하지 않음 (처음 발견된 값에 순위를 먼저 부여)
rank(-vscore, ties.method = 'max')   # 동순위를 인정하며 큰 값을 사용
rank(-vscore, ties.method = 'min')   # 동순위를 인정하며 작은값을 사용

> rank(-vscore, ties.method = 'first') # 동순위를 인정하지 않음 (처음 발견된 값에 순위를 먼저 부여)
[1] 1 2 3 4 5 6
> rank(-vscore, ties.method = 'max')   # 동순위를 인정하며 큰 값을 사용
[1] 1 3 3 4 5 6
> rank(-vscore, ties.method = 'min')   # 동순위를 인정하며 작은값을 사용
[1] 1 2 2 4 5 6

 

library(dplyr)

dplyr::dense_rank(vscore)

> dplyr::dense_rank(vscore)
[1] 5 4 4 3 2 1

 

# 예) emp.csv 파일을 읽고 급여가 높은 순서대로 5등까지 직원 추출(동순위 인정, 연속적이지 x)

emp <- read.csv('emp.csv')

plyr::arrange(emp, desc(SAL))

emp$SALRANK <- rank(-emp$SAL, ties.method = 'min')
emp

emp[emp$SALRANK <= 5, ]

> emp[emp$SALRANK <= 5, ]
   EMPNO ENAME       JOB  MGR        HIREDATE  SAL COMM DEPTNO
4   7566 JONES   MANAGER 7839 1981-04-02 0:00 2975   NA     20
6   7698 BLAKE   MANAGER 7839 1981-05-01 0:00 2850   NA     30
8   7788 SCOTT   ANALYST 7566 1987-04-17 0:00 3000   NA     20
9   7839  KING PRESIDENT   NA 1981-11-17 0:00 5000   NA     10
13  7902  FORD   ANALYST 7566 1981-12-03 0:00 3000   NA     20
   SALRANK
4        4
6        5
8        2
9        1
13       2

 

library(plyr)
ddply(emp, .(DEPTNO), transform, vrank = rank(-SAL, ties.method = 'min'))

> ddply(emp, .(DEPTNO), transform, vrank = rank(-SAL, ties.method = 'min'))
   EMPNO  ENAME       JOB  MGR        HIREDATE  SAL COMM DEPTNO
1   7782  CLARK   MANAGER 7839 1981-06-09 0:00 2450   NA     10
2   7839   KING PRESIDENT   NA 1981-11-17 0:00 5000   NA     10
3   7934 MILLER     CLERK 7782 1982-01-23 0:00 1300   NA     10
4   7369  SMITH     CLERK 7902 1980-12-17 0:00  800   NA     20
5   7566  JONES   MANAGER 7839 1981-04-02 0:00 2975   NA     20
6   7788  SCOTT   ANALYST 7566 1987-04-17 0:00 3000   NA     20
7   7876  ADAMS     CLERK 7788 1987-05-23 0:00 1100   NA     20
8   7902   FORD   ANALYST 7566 1981-12-03 0:00 3000   NA     20
9   7499  ALLEN  SALESMAN 7698 1981-02-20 0:00 1600  300     30
10  7521   WARD  SALESMAN 7698 1982-02-22 0:00 1250  500     30
11  7654 MARTIN  SALESMAN 7698 1981-09-28 0:00 1250 1400     30
12  7698  BLAKE   MANAGER 7839 1981-05-01 0:00 2850   NA     30
13  7844 TURNER  SALESMAN 7698 1981-09-08 0:00 1500    0     30
14  7900  JAMES     CLERK 7698 1981-12-03 0:00  950   NA     30
   SALRANK vrank
1        6     2
2        1     1
3        9     3
4       14     5
5        4     3
6        2     1
7       12     4
8        2     1
9        7     2
10      10     4
11      10     4
12       5     1
13       8     3
14      13     6