한의대 생활

A <- matrix(c(1, -1, 2, 3), nrow=2)
A
#      [,1] [,2]
#[1,]    1    2
#[2,]   -1    3

#### 2by2 matrix의 determinant 구하기 ####
# A(a b,c d)  D(A) = ad-bc

# 1. 사용자 정의 함수로 det() 흉내내기
det_f <- function(A){
   d <- A[1, 1] * A[2, 2]  -  (A[1, 2] * A[2, 1])
   return(d)
}
det_f(A)

# 2. 내장함수 쓰기 det()
det(A)


#### 2by2 matrix의 역행렬(inverse) 구하기 ####
# 앞에 1/(ad-bc) 곱하기
# a와 d 바꾸기 + b와 c에 - 달아주기

# 1. 사용자 정의함수
inv_f <- function(A){
   B = matrix(, nrow=2, ncol=2) # 빈행렬이지만, 2by2 폼 만들어놓기
   B[1, 1] <- A[2, 2]
   B[2, 2] <- A[1, 1]
  
   B[1, 2] <- -(A[1, 2])
   B[2, 1] <- -(A[2, 1])
  
   # 1/ad-bc 곱해주기
   B <- (1/det(A)) * B
   return( B )
}

inv_f(A)

# 2. 검산    A  %*%  A역행렬 = I (단위행렬)
  ( A %*% inv_f(A) )

# 3. 역행렬 내장함수 solve()와 검산
# ****1.1234134214 e-16같은게 나오면, 전체를 반올림 해주면 된다.
solve(A)
A %*% solve(A)
#             [,1] [,2]
#[1,] 1.000000e+00    0
#[2,] 1.110223e-16    1

round( A %*% solve(A) , 10)
#     [,1] [,2]
#[1,]    1    0
#[2,]    0    1

R markdown

  • 패키지 설치
    image

  • 아래와 같이 생성
    -  title + HTML선택만 해준다.
    image

    image
    image


  • 아래 스크린샷 부분은 설치 방법 & 주석이므로 제거한다.
    image


  • R코드는 ```{r} 으로 시작  ```으로 끝을 낸다.
    image


  • 기본 제공되어있는 코드로 상단의 Knit - Knit to HTML를 눌러보자.
    image


  • 저장시 아무 확장자도 안주어야지 .Rmd로 저장된다. html로 하면 안됨. -. 알아서 .html도 생성된다.
    image


  • 생성된 R markdown - html양식
    - echo = FALSE 라는 인자가 들어간 부분은 -> 코드( plot(pressure) )없이 결과값만 뜬다.
    image
    image


연습해보기

연습한 Rmarkdown.html 코드 복사해넣기

Now we are going to practice matrix functions!! (그냥 글자)

글자 크게(샵 1개)

작은 제목(샵 2개)

nrow = 인자 없이 matrix 생성 -> n by 1 (1열로 나옴)

A <- matrix(c(1, -1, 2, 0, 3, 4))
A
##      [,1]
## [1,]    1
## [2,]   -1
## [3,]    2
## [4,]    0
## [5,]    3
## [6,]    4

nrow = 인자 설정한 matrix 와 단순array

byrow = TRUE 옵션을 주지 않으면, 열을 하나씩 채운다.

A <- matrix(c(1, -1, 2, 0, 3, 4), nrow = 2)
A
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]   -1    0    4
B <- array(1:3)
B
## [1] 1 2 3
is.matrix(A)
## [1] TRUE
is.matrix(B)
## [1] FALSE

array에 2번째 인자인 dimension인자 (c(n,m))을 입력하면 matrix가 된다.

2 by 3에서 모자란 것은 1열씩 차례대로 채운다. array()로 생성하는 matrix에는 byrow옵션이 없다.

A = matrix(c(1, -1, 2, 0, 3, 4), nrow = 2, byrow = TRUE)
A
##      [,1] [,2] [,3]
## [1,]    1   -1    2
## [2,]    0    3    4
C = array(1:3, c(2, 3))
C
##      [,1] [,2] [,3]
## [1,]    1    3    2
## [2,]    2    1    3
is.matrix(C)
## [1] TRUE

행렬의 합, 차, 곱(각 성분들의 곱이 되어버림.) vs 외적%*% ( 양식 맞춰줘야함!** )

A
##      [,1] [,2] [,3]
## [1,]    1   -1    2
## [2,]    0    3    4
C
##      [,1] [,2] [,3]
## [1,]    1    3    2
## [2,]    2    1    3
A+C
##      [,1] [,2] [,3]
## [1,]    2    2    4
## [2,]    2    4    7
A-C
##      [,1] [,2] [,3]
## [1,]    0   -4    0
## [2,]   -2    2    1
A*C # 각 성분들의 곱이 되어버림
##      [,1] [,2] [,3]
## [1,]    1   -3    4
## [2,]    0    3   12
#A %*% C # a by b  외적 b by c 형태여야함.

t(C) # 형태변환(대각선기준 접기!)
##      [,1] [,2]
## [1,]    1    2
## [2,]    3    1
## [3,]    2    3
A %*% t(C)
##      [,1] [,2]
## [1,]    2    7
## [2,]   17   15
A == C # logical 결과(mask)
##       [,1]  [,2]  [,3]
## [1,]  TRUE FALSE  TRUE
## [2,] FALSE FALSE FALSE
t(t(A)) == C
##       [,1]  [,2]  [,3]
## [1,]  TRUE FALSE  TRUE
## [2,] FALSE FALSE FALSE

#### Windows10 MySQL 설치를 위한 APMSETUP7 설치 ####
# APM : Apache, Php, MySQL을 한번에 설치해준다.----> localhost를 치면 웹서버가 보여야 정상.
# http://kldp.net/apmsetup/release/ 에서 최신버전 다운로드
# 3221-APMSETUP7_2010010300.exe
# 관련 사항 확인 : http://nittaku.tistory.com/375

#### MySQL monitor ####
참고페이지 : http://nittaku.tistory.com/375?category=764930
# cmd 켬
# database server 접속 : mysql -uroot -p
# database 확인 : show databases;
# database 사용 : use [해당 db명];
# 해당db속 table 확인 : show tables;
# 해당table속 모든칼럼(*) 가져오기 : select * from 테이블명;


#### 샘플 데이터 다운로드 ####
# cmd로 설명한 페이지
: http://mystyle1057.tistory.com/272
# sample db다운 : http://www.mysqltutorial.org/mysql-sample-database.aspx
# cmd에서 압축을 푼 뒤 해당폴더에 진입mysql monitor에 접속 : 해당폴더 > mysql -uroot -p
# cmd에서 해당폴더에 <source 파일명.sql;> 을 통해 설치 : 해당폴더 > source mysqlsampledatabase.sql
# 기본폴더에서도 목록 보이게 됨 : cmd > mysql -uroot -p > show databases;
image

# *** classicmodel 이라는 db에서 table 중 employees table을 불러올 것임 : use classicmodels; > show tables; > select * from employees;
image



#### DB 확인하기 ####
# cmd > mysql -uroot -p >
# show databases;
# use classicmodels;
# show tables;
# select * from employees;
+-#---------------+-----------+-----------+-----------+---------------------------------+------------+-----------+----------------------+
   #| employeeNumber | lastName  | firstName | extension | email                           | officeCode | reportsTo | jobTitle             |
   #+----------------+-----------+-----------+-----------+---------------------------------+------------+-----------+----------------------+
   #|           1002 | Murphy    | Diane     | x5800     | dmurphy@classicmodelcars.com    | 1          |      NULL | President            |
   #|           1056 | Patterson | Mary      | x4611     | mpatterso@classicmodelcars.com  | 1          |      1002 | VP Sales             |
   #|           1076 | Firrelli  | Jeff      | x9273     | jfirrelli@classicmodelcars.com  | 1          |      1002 | VP Marketing         |
   #|           1088 | Patterson | William   | x4871     | wpatterson@classicmodelcars.com | 6          |      1056 | Sales Manager (APAC) |
   #|           1102 | Bondur    | Gerard    | x5408     | gbondur@classicmodelcars.com    | 4          |      1056 | Sale Manager (EMEA)  |
   #|           1143 | Bow       | Anthony   | x5428     | abow@classicmodelcars.com       | 1          |      1056 | Sales Manager (NA)   |
   #|           1165 | Jennings  | Leslie    | x3291     | ljennings@classicmodelcars.com  | 1          |      1143 | Sales Rep            |
   #|           1166 | Thompson  | Leslie    | x4065     | lthompson@classicmodelcars.com  | 1          |      1143 | Sales Rep            |
   #|           1188 | Firrelli  | Julie     | x2173     | jfirrelli@classicmodelcars.com  | 2          |      1143 | Sales Rep            |
   #|           1216 | Patterson | Steve     | x4334     | spatterson@classicmodelcars.com | 2          |      1143 | Sales Rep            |
   #|           1286 | Tseng     | Foon Yue  | x2248     | ftseng@classicmodelcars.com     | 3          |      1143 | Sales Rep            |
   #|           1323 | Vanauf    | George    | x4102     | gvanauf@classicmodelcars.com    | 3          |      1143 | Sales Rep            |
   #|           1337 | Bondur    | Loui      | x6493     | lbondur@classicmodelcars.com    | 4          |      1102 | Sales Rep            |
   #|           1370 | Hernandez | Gerard    | x2028     | ghernande@classicmodelcars.com  | 4          |      1102 | Sales Rep            |
   #|           1401 | Castillo  | Pamela    | x2759     | pcastillo@classicmodelcars.com  | 4          |      1102 | Sales Rep            |
   #|           1501 | Bott      | Larry     | x2311     | lbott@classicmodelcars.com      | 7          |      1102 | Sales Rep            |
   #|           1504 | Jones     | Barry     | x102      | bjones@classicmodelcars.com     | 7          |      1102 | Sales Rep            |
   #|           1611 | Fixter    | Andy      | x101      | afixter@classicmodelcars.com    | 6          |      1088 | Sales Rep            |
   #|           1612 | Marsh     | Peter     | x102      | pmarsh@classicmodelcars.com     | 6          |      1088 | Sales Rep            |
   #|           1619 | King      | Tom       | x103      | tking@classicmodelcars.com      | 6          |      1088 | Sales Rep            |
   #|           1621 | Nishi     | Mami      | x101      | mnishi@classicmodelcars.com     | 5          |      1056 | Sales Rep            |
   #|           1625 | Kato      | Yoshimi   | x102      | ykato@classicmodelcars.com      | 5          |      1621 | Sales Rep            |
   #|           1702 | Gerard    | Martin    | x2312     | mgerard@classicmodelcars.com    | 4          |      1102 | Sales Rep            |
   #+----------------+-----------+-----------+-----------+---------------------------------+------------+-----------+----------------------+#



#### RMySQL 설치 및 사용 ####
# R은 아주 큰 DB분석에 좋지 않다. 미리 sql에서 추출해서 분석하는 용도로 사용하는게 좋다.

# 1. RMySQL 패미지 설치 및 사용
install.packages("RMySQL")
library(RMySQL)


# 2. database server에 연결하기
# - mysql server가 돌아가는 상태여야 한다.
image

mydb <- dbConnect(MySQL(), user='root', password='rkqhwk12', dbname = 'classicmodels')
mydb


# 3. 쿼리문으로 db에서 테이블들 확인하기
# - 쿼리문을 날릴 때는, 연결된 database를 첫번째 인자로 주고 날린다.

result <- dbGetQuery(mydb, 'show tables;')
result

# 4. 쿼리문으로 table속 row개수 다 세기
dbGetQuery(mydb, 'select count(*) from employees;') # 32

# 5. 쿼리문으로 db속 table 가져오기
tbl <- dbGetQuery(mydb, 'select * from employees;')
tbl


# 여기서부터는 R 문법
# 6. paste()로  2개의 문자열 컬럼을 합친 것을 새로운 칼럼으로 생성하기기***
tbl$name <- paste(tbl$firstName, tbl$lastName)

# 7. 합쳐졌던 2개 칼럼 버리기***(버릴 때는, 인덱싱에서 제외하여 새로운 df를 만들어서 버림)
# 이름을 제일 처음으로 + 2개(2, 3번칼럼) 버리기
newdf <- tbl[c( ncol(tbl), 1, 4:(ncol(tbl)-1)  )]
newdf

# 8. ***gsub(, , 칼럼명)을 이용하여 특정 문자(NA 등) 치환하기***
# NA가 문자열로 포함된 reportsTo 칼럼에서 NA을 치환해준다.
newdf$reportsTo <- gsub('NA', '', newdf$reportsTo) # 문자열 NA만 있던 경우, ''로 대체하면  <NA>의 진짜 결측값을 가진다.
newdf

# 9. nuemeric/factor가  character로 되어있다면 바꿔주기 --> *** summary()에서 통계정보가 안나오기 때문에
# factor화는 factor()도 있었는데, 칼럼단위로으로... 해주려면... as.factor()*** /
# 칼럼단위라도 a$b <- factor(a$b)사용하기도 했었다. ( ggvis - http://nittaku.tistory.com/369)
str(newdf)
summary(newdf)

newdf$officeCode <- as.factor(newdf$officeCode)
str(newdf)
summary(newdf) # office의 범주중 1이 가장 많다..

# 10. 날짜 정보(2018-1-1)같은 정보가 character로 되어있다면  as.Date()로 바꿔주자.***
# 여기에는 없음


#### 11. database 서버와 연결 끊어주기 #### ****
# mysql서버와의 연결만 끊코, db객체는 살아있다.
dbDisconnect(mydb)

MySQL을 위한 APMSETUP7 설치

http://kldp.net/apmsetup/release/ 에서 최신버전 다운로드

*2010버전이 최신이고, 홈페이지는 사라진 상태, win 32비트용(? 64bit에서졷 잘돌아간다) 각 버전은 아래와 같음


  1. 크롬창에 localhost를 쳐서 웹서버 정상 설치되었는지 확인하기
    image


  2. 설치된 폴더( C:\apm_setup)으로 가서 각 파일들 확인하기
    image
    • php.ini : php설정 파일
    • Server 폴더 > MySQL5 > data > my.ini : MySQL 설정 파일
      image


  3. MySQL 클라이언트 파일을 통한 MySQL 접속하기
    • Win + R : cmd 입력
      image

    • mysql -uroot -p   입력후 기본설정된 비밀번호 입력
      apmsetup
      image
      -u : user
      root : 기본적인 사용자계정
      -p : apmsetup 으로 기본설정 되어있다. 나중에는 변경해야한다.


    • show databases;   --> 3개의 데이터 베이스 확인
      image

workbench로 mysql 다루기


  • apmsetup으로 mysql 서버가 설치 된 상황이라면,
    아래와 같이 인식되더라. 비밀번호 기본 : apmsetup을 통해 접속하자
    image
    image



웹기반의 phpMyAdmin 으로 다루기

  • APMSETUP에서 제공되는 APMSETUP 모니터를 작업표시줄에서 확인한 뒤,
    imageimage

  • 우클릭을 통해 메뉴 > MySQL관리 (M)에 들어가면, phpMyAdmin이 확인된다.
    imageimage


  • 사용자명과 암호에는  rootapmsetup을 적어준다.
    - 이것 역시 MySQL client의 종류 중 하나이다.
    image

    Database server와  Database Client를 살펴보자.
    image

  • 데이터베이스 탭을 보자.
    3개의 기본 db들이 있고, 클릭하면 여러개의 table들이 있다.
    image


  • MySQL 서버의 root 계정 비밀번호 변경
    - apmsetup 모니터 > 우클릭 > MySQL root 패스워드 변경

    imageimage

# 데이터 준비
mtcars
str(mtcars)
head(mtcars)

# aggregate()를 이용한,  cyl칼럼에 따른, mpg칼럼의 평균값들
aggregate(mtcars$mpg, by=list(mtcars$cyl), mean)

#### ***사용자 정의함수 + if문을 이용해서 aggregate()흉내내기*** ####
# udf의 ()인자에 cyl칼럼이 들어갈 것임...
# 그값이 4, 6, 8일 때,, 그 row들을 인덱싱해서  mpg의 평균
# 만약 함수안에서 변수에 안담기고 함수식만 있다면 -> R은 알아서 return을 해주는 기능이 있다.   변수에 담그면 반드시 return()
mean_by_cyl <- function(x){
   if(x == 4){
     # aggregate로 쓸 경우 : aggregate(mtcars$mpg, by=list(mtcars$cyl), mean)  [1, 2]
     return(    mean( mtcars[ mtcars$cyl == 4, "mpg"] )    )
   }else if(x == 6){
     return(    mean( mtcars[ mtcars$cyl == 6, "mpg"] )    )
   }else if(x == 8){
     return(    mean( mtcars[ mtcars$cyl == 8, "mpg"] )    )
   } else{
     print("잘못 입력되었습니다. 4 or 6 or 8 중에 입력해주세요")
   }
} # if문 끝

mean_by_cyl(4)
mean_by_cyl(6)
mean_by_cyl(8)

mean_by_cyl(7)


# 4, 6, 8은 들어오는 값이니 x로 대체하기
# my) 4 or 6 or 8 인 경우를,,, %in% 으로 대체하기***
mean_by_cyl <- function(x){
   if(x %in% c(4, 6, 8)){
     return(    mean( mtcars[ mtcars$cyl == x, "mpg"] )    )
   }else{
     print("잘못 입력되었습니다. 4 or 6 or 8 중에 입력해주세요")
   }
} # if문 끝

mean_by_cyl(4)
mean_by_cyl(6)
mean_by_cyl(8)
mean_by_cyl(7)

#### **** if문을 써서 aggregate()를 흉내낼 때의 장점 -> 경우의 수별로 문자열 띄울 수 있다.####
# *** return( '문자열', 변수, '문자열') 처첨 섞인 경우에는
# 바로 return 안되므로 paste로 묶어서 하나로 return한다 ***
# *** round( a, 2) --> 소수점 2번째 자리**까지** 표시

mean_by_cyl <- function(x){
   if(x == 4){
     a <- round(mean( mtcars[ mtcars$cyl == 4, "mpg"] ), 2)
     return( paste0('The avg mile per gallon of ', x, ' cylinder car is ', a))
   }else if(x == 6){
     a <- round(mean( mtcars[ mtcars$cyl == 6, "mpg"] ), 2)
     return( paste('The avg mile per gallon of ', x, ' cylinder car is ', a, sep=''))
   }else if(x == 8){
     a <- round( mean( mtcars[ mtcars$cyl == 8, "mpg"] ) , 2)
     return( paste('The avg mile per gallon of ', x, ' cylinder car is ', a, sep=''))
   } else{
     print("잘못 입력되었습니다. 4 or 6 or 8 중에 입력해주세요")
   }
} # if문 끝

mean_by_cyl(4)
mean_by_cyl(6)
mean_by_cyl(8)

x <- c(1:10)
y <- x^2 - x + 10
plot(x, y)

# type
plot(x, y, type = "p" ) # 점 출력 - default
plot(x, y, type = "n" ) # 아무것도 출력x
imageimage
plot(x, y, type = "S" ) # 계단식S : 해당값에서 올라갔다가 다음값으로 감
plot(x, y, type = "s" ) # 계단식s : 해당값에서 다음값으로 갔다가 올라감
imageimage
plot(x, y, type = "h" ) # bar와 비슷한데 선이 올라옴

image


# col
plot(x, y, type = "h", col = "blue" )
image

# pch - point의 모양바꾸기
plot(x, y, type = "p", col = "blue", pch = 1) # 동그라미 - default
plot(x, y, type = "p", col = "blue", pch = 2) # 세모
plot(x, y, type = "p", col = "blue", pch = 3) # +
plot(x, y, type = "p", col = "blue", pch = 4) # X
plot(x, y, type = "p", col = "blue", pch = 5) # 다이아몬드

# *** par(mfrow=c(nrow,ncol) + for()문을 이용하여 여러개 plot 동시에 그리기 ***
par(mfrow = c(2,4))
for(i in 1:8){
   plot(x, y, type ="p", col="blue", pch = i)
}
image


par(mfrow = c(2,4))
for(i in 9:16){
   plot(x, y, type ="p", col="blue", pch = i)
}

image


types = c("p", "l", "o", "b", "c", "s", "S", "h") # "o" = 점+선 overlap
par(mfrow = c(2,4))
for(i in 1:8){
   plot(x, y, type = types[i], col="blue")
}

image

#### "MASS" package 와 Aids2 데이터 ####
Aids2 # 패키지가 안깔리면 object를 찾을 수 없다고 뜬다.

install.packages("MASS") # 1. MASS 패키지 설치
library(MASS) # 2. MASS 패키지 사용
data(Aids2) # 3. MASS패키지 속의 Aids2 data사용

Aids2
str(Aids2) # 4. Aids2 데이터 구조 확인
?Aids2 # 5. 데이터 설명보기

head(Aids2) # 6. 데이터 간략하게 보기


#### summary() ####
summary(Aids2)

# age가 0세인 사람도 있는지 위치 확인
Aids2[ Aids2$age == 0, ]
Aids2[ which(Aids2$age == 0), ]


# 살아있는 사람 명수 확인
Aids2[ Aids2$status == "A", ]
length(Aids2[ Aids2$status == "A", ]) # df의 length는 칼럼수가 나와버림..
nrow(Aids2[ Aids2$status == "A", ])


#### aggregate( df$칼럼인덱싱, by=***list(df$기준칼럼인덱싱1, 2) ~에 따른, 통계함수 mean) ####
# *** 살아있는 사람들 중, 성별에 따른, age의 평균
# - sum은 해봤자 의미가없음.. 나이라서

# 1) 살아있는 사람만 인덱싱으로 일단 뽑는다.***
Alive <- Aids2[ Aids2$status == "A", ]

# 2) aggregate()함수를 이용해 ***기준칼럼에 따른 특정칼럼의 평균을 구한다.***
aggregate(Alive$age, by=list( Alive$sex ), mean)

# 3) 죽은사람들 중 성별에 따른 age의 평균 도 마찬가지
Dead <- Aids2[ Aids2$status == "D", ]
aggregate(Dead$age, by=list( Dead$sex ), mean)

####  ***살/죽은 사람을 인덱싱으로 뽑는 과정 없이, 기준칼럼2로 등록하여 한방에 aggregate()로 뽑아보기*** ####
# *** 기준을 2개를 넣는 방법 *** my)2개이상 들어갈 수 있어서,,,미리 by=에 기본적으로 list()를 적어주었구나..
aggregate(Aids2$age, by = list(Aids2$sex, Aids2$status), mean)


#### 1. binomial distribution ####
# 이항분포 : 독립적인 확률을 가진 상태에서, 여러번 던진 경우 앞면이 나오는 확률
# 동전 10번 던져서 3번 앞면이 나올 확률
# - dbinom(성공 횟수, 전체횟수, 각 확률)

dbinom(3, 10, 0.5)
# 4번
dbinom(4, 10, 0.5)
# 5번 째에 peak
dbinom(5, 10, 0.5)
# 6번 부터 다시 작아짐
dbinom(4, 10, 0.5)

#### 2. hypergeometric distribution ####
# populartion size가 있고 -> 추출한 sample size가 따로 있다.
# 10개 공 중의 3개는 빨간색공 / 7개는 흰색공 일 때,
# 추첨을 해서 5개를 뽑았을 때, 빨간공이 2개일 확률
# ex> 한 반에 남자70% 여자30% 총 20명 -> 10명 선발시 남자가 3명일 확률
# - dhypter(남자의 확률, populartion에서 남자의 size, population size에서 여자의 size, 추출한 sample size)

#이항분포( 10번을 뽑아서 3명이 남자일 확률 )
# - dbinom(3명이 남자일 확률, 10명을 뽑았을 때, 각 뽑힐 확률은 0.4)
dbinom(3,10,   0.4)

#**** 초기하 분포 (남+여 10명 중에 남자가 4명 여자가 6명 있다, 여기서 10명을 뽑았을 때, 남자가 3명일 확률은?)
# ->  성공횟수 10중 3 +  이항분포의 확률(0.4)과 같은 population 4 / 10 을 유지하자. 나중 증명을 위해 ***
# -> 10명을 다뽑았는데 남자가 3명일 수없다. 다 뽑혀서 남자4 여자6이다. -> 확률0

# - dhyper(3명이 남자일 확률,    남자size 4명, 여자size 6명,     추출한 사람 10명)
dhyper(3,   4,6,   10) # 0

# 남4 여자6 중에 10명을 뽑았을 때 남자가 4명일 확률? -> 100% = 1
dhyper(4,   4,6,   가10) # 1

# *** 좀 의미있게 문제 바꾸기위해 전체size를2배 늘려보자.(이항분포 확률 0.4 + 성공횟수 10 중 3 유지)
# - 이항분포에서의 남자의 확률과 같은  0.4 + 성공횟수3 을 유지할 수 있도록,
# - 남8여12 중 10명을 뽑았을 때, 남자가 3명일 확률

dhyper(3,  8,12,   10) # 0.24


#### 3. ***이항분포의 확률(0.4)와 같은 확률+ 성공횟수(10중3)을 가진 초기하분포(dhyper)는 전체(population) size가 커지면---> 이항분포(dbinom)과 같아진다. ####

dbinom(3, 10, 0.4) #0.214

dhyper(3,   4,6,     10) # 처음시작 0
dhyper(3,   8,12,    10) # 전체size 2배 0.24
dhyper(3,   12,18,   10) # 전체size 3배 0.233
dhyper(3,   20,30,   10) # 전체size 5배 0.225

#*** 프로그래밍적으로 코드 작성***
# 이항분포의 횟수 4+6 중 3   에서 시작해서
# 전체 size를 100배까지 늘려줄 때,( population size를 4*100 + 6*100 까지 늘임)
# 그릇에 담아서 확률이 이항분포와 같아지는지 확인


a = 100
approx <-numeric(length=a) # a개의 개수(length)를 숫자형 자료벡터(확률이 들어갈 그릇)

for( i in 1:a){
   approx[i] <- dhyper(3,    4*i,6*i    , 10)
}
approx
image


# ***100개의 확률이 어디로 근접하는지 plot으로 확인하자
# approx[1]은 확률이 0이라서,, 그래프가 안그려지더라...?  2부터..
plot(approx[2:100])
image


# *** 초기하분포 확률 plot에다가  이항분포의 확률을 선으로 그려주자.
# *abline( h = 값) - 직선을 그려주는데 h(수평선)을 그려준다.
abline(h = dbinom(3, 10, 0.4), col="red")
image


# 값 차이
approx - dbinom(3, 10, 0.4) # 마지막 100번째엔 0.0005 차이



#### ggvis 그래프 패키지 ####
# 칼럼명(변수) 앞에 ~가 있어야 변수인지 알아먹는다.***
# 겹쳐서 그릴 수 있는 것이 최대 장점이다.***

install.packages("ggvis")
library(ggvis)


#데이터 준비
mtcars

# 기본plot
plot(mtcars$mpg, mtcars$wt)
image

#### ***파이프라인 + ggvis ####
# 점찍기
mtcars %>%
   ggvis(~mpg, ~wt) %>% # 기본적으로 layer_point()로 점을 찍는다.
   layer_points() # 점찍기


  
# 라인그리기
mtcars %>%
   ggvis(~mpg, ~wt) %>%
   layer_lines()
image

# bar 그리기
mtcars %>%
   ggvis(~mpg, ~wt) %>%
   layer_bars()
image

# smooth 하게 이어주기
mtcars %>%
   ggvis(~mpg, ~wt) %>%
   layer_smooths()
image

# 점 + smooth 겹쳐 그리기
mtcars %>%
   ggvis(~mpg, ~wt) %>%
   layer_points()   %>%
   layer_smooths()
image


# 점에 색깔만 채우기( fill:= "색이름" )
# ggvis(, , fill:="red)  := 에 주의할 것.!
mtcars %>%
   ggvis(~mpg, ~wt, fill:="red") %>%
   layer_points()   %>%
   layer_smooths()

image



#*** x축, y축 칼럼 이외에 기준칼럼으로 점의 색 채우기( fill = ~칼럼명 )
mtcars %>%
   ggvis(~mpg, ~wt, fill = ~cyl) %>%
   layer_points()   %>%
   layer_smooths()

image


# *** 하지만, cyl은 현재 numeric(수치형, 연속형)의 자료형을 가지고 있어서,
# *** 4, 6, 8의 범주형을 가지고 있음에도 불구하고 그래프에서 <연속형 scalebar>를 가지고 있다.
# *** factor()범주형으로 cyl칼럼을 바꿔주고 다시 해보자.

mtcars$cyl <- factor(mtcars$cyl)
str(mtcars)
mtcars %>%
   ggvis(~mpg, ~wt, fill = ~cyl) %>%
   layer_points()   %>%
   layer_smooths()
### scalebar가 사라지고 범주형으로 딱딱 잘라서 보이는 범례가 나타난다.
image



# 축 격자들 더 촘촘하게 만들어주기 + 축 이름 달기 ***
# add_axis("x or y", title = "MPG", values = c(0:35) 구간에 찍힐 값 직접 명시 )
# add_axis("x or y", title = "MPG", subdivide = 4 기존 1구간안에 추가될 하위bar 개수)
mtcars %>%
   ggvis(~mpg, ~wt, fill = ~cyl) %>%
   layer_points()   %>%
   layer_smooths()  %>%
   add_axis("x", title = "MPG", values = c(0:35))

image



# 필요없는 구간이 나와서 범위 바꾸기
mtcars %>%
   ggvis(~mpg, ~wt, fill = ~cyl) %>%
   layer_points()   %>%
   layer_smooths()  %>%
   add_axis("x", title = "MPG", values = c(10:35))


# y축도 똑같이 해준다.
mtcars %>%
   ggvis(~mpg, ~wt, fill = ~cyl) %>%
   layer_points()   %>%
   layer_smooths()  %>%
   add_axis("x", title = "MPG", values = c(10:35)) %>%
   add_axis("y", title = "WT", subdivide = 4 ) # 4.5 와 5.0이 구간안에 .6 .7 .8 .9의 4개 하위bar 추가

image

기존 방식

기준칼럼의 각 값별로 인덱싱 -> 3개의 df에서 특정칼럼만 뽑기 -> 3개의 칼럼을 cbind()로 묶어주기(matrix로 나옴) -> 관찰


#### tapply() : 빠르게 인덱싱하여, 통계(합or평균) 구하기 ####
#  기준칼럼의 각 값별로 쪼개서 -> 특정한 칼럼의(남자 or 여자의 평균, 합)을 얻고 싶을 때
# cyl컬럼의 각 값별로 milages의 평균 구하기

# 데이터 준비
mtcars



#### 기존의 방법으로 구해보기 ####
class(mtcars)
str(mtcars)

# 필요한 1번째, 2번째 칼럼만 뽑아 새로운 데이터프레임 생성
newdata <- mtcars[, 1:2] #*** mtcars[1:2] 1차원형태로 인덱싱해도 df의 칼럼이 뽑힌다.
newdata

# cyl 의 각 값별로 mpg데이터 따로 가져오기
cyl_4 <- newdata [ newdata$cyl == 4, "mpg"]
newdata [ which(newdata$cyl == 4), "mpg"] # 위에 것과 동일한 결과

cyl_6 <- newdata [ newdata$cyl == 6, "mpg"]
cyl_8 <- newdata [ newdata$cyl == 8, "mpg"]

# cyl의 각 값별 mpg 평균구하기
mean(cyl_4)
mean(cyl_6)
mean(cyl_8)

# **** cbind()로 칼럼방향으로 묶어주기
# **** cbind()의 결과값을 보니 [1,] 형태의 1 by 3 matrix!***
cbind(mean(cyl_4), mean(cyl_6), mean(cyl_8))


#### tapply(df$특정칼럼, df$기준범주컬럼, 통계함)을 통한 기준(범주)칼럼의 값 별로 특정칼럼의 통계빠르게 구하기 ####
# - tapply()
tapply(mtcars$mpg, mtcars$cyl, mean)
tapply(mtcars$mpg, mtcars$gear, sum)

#### dot chart ####

# 일반 plot()
x <- 1:10
y <- x-1
plot(x, y) #plot(y~x) 동일한 문법
plot(y~x)

#### 1. dotchart의 x(index)는 이산형( ex>문자열의 행이름 같은 or 수치형벡터 or 행렬 ) = 연속형 X ####
# *** x가 이산형태의 데이터야지 dotchart를 그릴 수 있다.
dotchart(y~x) #Error 'x'는 반드시 수치형 벡터 또는 행렬이어야 합니다.

#### 2. dotchart($칼럼인덱싱, labels, cex)는 < plot(x, y)과는 x축과 y축이 서로 바뀌어서 index가 y축에 > dot선을 가지고 나타난다. ####
# dotchart의 df자리에는 $컬럼인덱싱을 해주면, index가 (y축)으로서 간다.
#데이터 준비
mtcars # mpg(마일리지), cyl(실린더), gear(기어 수) 칼럼만 사용할 것이다.
mtcars$mpg

# 1) df의 한 칼럼(mpg칼럼)을 dotchart()에 넣어보자.
plot(mtcars$mpg) # plot()의 index는 각 차 이름(row명)가 숫자로서 나타남
image
dotchart(mtcars$mpg) #  index - 차이름(row.names)들이 y축으로 가며, 각 차이름들에 대해 dot들이 연결된다.
image

# 2) *** index(y축)가 행번호가 찍혀야하는데, 행 이름(문자열)이 기재되어있는 df라면 비어있게 되므로,  labels = row.names()라 기재해준다.
row.names(mtcars)
dotchart(mtcars$mpg, labels = row.names(mtcars))
image

# 3) *** y축(index) 글자의 크기를 줄일려면, cex = 0.7을 보통 주면 된다 *** ####
dotchart(mtcars$mpg, labels = row.names(mtcars), cex=0.7)
image


#### 3. 이제  dotchart()로 표현될 $mpg칼럼의 점들이 $cyl 컬럼에 대해서 어떻게 다른지 알아보자. ####
# 1) ***dotchat()에 그려지는 mpg칼럼에 대해 오름차순으로 먼저 정렬한다.
# *** df [ order ( $칼럼인덱싱 ),   ] *** 으로 한 칼럼에 대해 *** 오름차순 sort *** 시킨다.
carmpg <- mtcars[order(mtcars$mpg), ]
carmpg

# 2) ***mpg칼럼에 대해 오름차순 정렬된 df에  <- 기준 범주(그룹)를 적용할  칼럼 하나를 factor화(factor()) 하기 ####
참고) https://thebook.io/006723/ch02/03/06/ 
     # - factor()는 연속적인 - 수치형(my)연속형) (Numeric)과 상반되는 개념인 범주형(categorical)자료형으로
     # - 1) 순서를 둘 수 있는 순서형(Ordinal)과 2) 비교불가능한 범주인 명목형(Nominal)로 구분된다.
     # *** 실험결과 여기서는 factor() 안만들고 해도 상관없더라... ***

carmpg$cyl # cyl칼럼은 8 or 6 or 4이다.***연속형의 값이 아니라, 각각을 <구분해주는 요소(Factor)>들을 의미한다. ex> 남/여  1/2는  값의 크고작은 수치가 중요한게 아니라 <서로를 구분해주는 카테고리형, 범주형의 Factor>이다.
carmpg$cyl <- factor( carmpg$cyl )

# factor화된 것 확인
class(carmpg$cyl) # "factor"
# my)
sapply(carmpg, FUN = "class")

# 3) dotchart()에 그려지는 칼럼(mpg)에 대해 sort한 새로운df를 dotchart()그리기
dotchart(carmpg$mpg, labels = row.names(carmpg), cex=0.7 )

# 4) *** dotchart 칼럼(mpg)에 대해,  범주를 두고 싶은 칼럼(cyl)의 값 별로 -> 새로운 color칼럼 만들기
#cyl칼럼의 요소들 확인해보기
table(carmpg$cyl) # 4 /6 /8 종류가 있다.
# ***color칼럼 <생성과 동시에 &칼럼인덱싱> + 행인덱싱자리에   범주적용컬럼의 각별로 조건문인덱싱  = color값 문자열 대입
carmpg$color [ carmpg$cyl == 4 ] <- "blue"
carmpg$color [ carmpg$cyl == 6 ] <- "green"
carmpg$color [ carmpg$cyl == 8 ] <- "red"


# 5) ***cyl값에 대한 color칼럼을 dotchart()의 color=인자로 넣어준다.
dotchart(carmpg$mpg, labels = row.names(carmpg), cex=0.7, color=carmpg$color )
image

# 6) *** 그래프보고 해석해보기
# - cyl 8개 짜리(=빨간색)일수록 mpg가낮은 편이다.
# - cyl 4개 짜리일수록 mpg가 높은 편이다.


# 7) *** cyl값(4, 6, 8)별로 그룹을 나눠서 dotchart()보기 groups = 그룹 나누는 기준이 될 $칼럼
dotchart(carmpg$mpg, labels = row.names(carmpg),
          groups = carmpg$cyl, cex=0.7, color=carmpg$color )
image

# 8) main인자로 dotchart 제목 주기
dotchart(carmpg$mpg, labels = row.names(carmpg),
          groups = carmpg$cyl, cex=0.7, color=carmpg$color,
          main = "Milage depending on numbers of cylinder")

# 9) xlab인자로 dotchart x축 label 주기
dotchart(carmpg$mpg, labels = row.names(carmpg),
          groups = carmpg$cyl, cex=0.7, color=carmpg$color,
          main = "Milage depending on numbers of cylinder",
          xlab = "Milage per Gallon")

image

image


### 최종해석 : cyl와 milage는 반비례하는 경향이 있다.

1. 논문 포스터 발표에 대한 장학생 모집

  • 올해 2기 대회
  • 기존 교수님들의 저명한 논문들이 많이 발표에 대한 불만을 가짐( 학부생 미래 인재 발굴인데...ㅠ 넘사벽 교수님들...)
  • 올해부터는 참신성, 창의성을 중점에 두고 평가한다고 함
  • 포스터 발표를 1차 목표로 본3 여름방학 2달간 딥러닝 hard 스터딩
  • 개강 후 모집기간까지 딥러닝으로 독성한약재(목통, 관목통, 방기)에 대한 image-classification 논문을 계획-설계-실험-평가 시행
  • 방제학 교수님과 후배2명의 협조 4개월 장기 스터디( 교수님 감사합니다 )
  • 논문 실험결과 정리과 동시에 ppt로 포스터 제작 (3개월 정도)



2. 전국 한의학 학술대회 오전에 학부생 포스터 발표 실시 (2018. 11. 25.   10:00 ~ 12:00)

  • 딥러닝 모델을 flask에 올려 약재를 감별할 수 있는 데모 사이트를 제작
  • 태블릿을 빌려 포스터발표와 함께 시연
  • 정성스레 그린 figure를 위주로 한 포스터 작성

imageimage



3. 결과 발표

  • 작년 기사를 보니 12. 28일 났었는데,  올해는 12. 31일 났음.
  • 새해 전에 처리를 하나봅니다.
  • 도와 주신 교수님, 후배님, 여자친구 모두 감사합니다.!


image

대충 정리한 것.

두 변수(2 그룹, matrix의 row들)들이 독립(귀무가설 참)이면 나와야하는 예상값을 가지고, 실제값과 차이를 제곱한 것을   다시 예상값으로 나눈 뒤  -> 각 요소 다 더해주기 -> 그 카이검정 결과값을 가지고 p-value 구해서 귀무가설 거짓 = 변수들 독립을 유의미하다고 확정하기  = 대립가설 채택하기

#### chi-square 카이제곱 검정 ####
# 변수(남/녀- matrix의 행들)들이 독립이냐? 아니면 각 변수들이 결과에 영향을 미치느냐
# ex> 남/녀 그룹이 영향을 줘서 yes/no가 나타났느냐 아니면 우연히 나타났느냐
#     2번째 여자그룹은 no가 훨씬 많으므로, 먼가 영향(유의미한 관계성, 그룹만의 관계성)이 있다?

#### 1. 데이터 준비 - 2by2 matrix ####
# 카이제곱 검정은 각 그룹의 합과 각 대답(yes / no)의 합이 필요하므로 matrix형태의 데이터를 준비한다.
# 1번째 남자 그룹의 yes 42 / no 30,    2번째 여자 그룹의 yes 50, no 87이라고 가정
data <- matrix( c(42, 30,
                             50, 87), nrow = 2, byrow = FALSE)
data


#### 2. 사용자 정의 함수를 일부만 완성시켜 chisq 검정함수의 귀무가설 참인지 알아보기.*** ####
# H0 귀무가설 : 남/녀는 차이가 없다. = 변수들 독립
# chisq 검정 중간 결과의 예상값 matrix : 귀무가설이 참이라면 <나와야 하는 예상된 값 matrix>

# Obs : Observer : 눈에 보이는 값, 여기서는 2by2 matrix
# 예상되는 값 : c(남자그룹 yes/no의 합 , 여자그룹 yes/no의 합) 외적%*% (남+여의 yes의 합, 남+여의 no의합)   /  matrix 전체의 합
# outer(a, b) : 외적, (a %*% b)와  동일
image
# rowSums(), colSums() : matrix의 (각 행, 각 열)별  합  벡터로 반환해주는 함수

rowSums(data) # 72 137
colSums(data) # 92 117
outer(rowSums(data), colSums(data)) # [1,] 6624 12604, [2,]8824 16029
outer(rowSums(Obs), colSums(Obs)) / sum(Obs) #[1,] 6624 12604 [2,] 8424 16029

#*** chisq 검정 사용자 정의 함수 일부만 보기(귀무가설 참인지)***
# 함수에서 나오는 예상 값이   실제값과 유사하면   귀무가설참=남녀독립
chisq <- function(Obs){
   Expected <- outer(rowSums(Obs), colSums(Obs)) / sum(Obs)
   return (Expected)
}

chisq(data) # [1,] 31.69378 60.30622 [2,] 40.30622 76.69378

#### 3. 카이검정 귀무가설에 대한 해석 ####
# 1) 만약 두 그룹(남/녀)가 대답(y/n)에 차이가 없다(=귀무가설 참= 남녀 독립 = 변수들 독립)면 나와야하는 예상 값
# chisq(data)
#       [,1]     [,2]
#[1,] 31.69378 60.30622
#[2,] 40.30622 76.69378

# 2) 실제 값 -> 카이검정 예상값과는 전혀 다른 값을 나타내므로 귀무가설 거짓 -> 남/녀라는 변수(그룹)은 y/n에 영향을 준다!!!!***

# data
#    [,1]   [,2]
# [1,]   42   50
# [2,]   30   87

#### 4. 사용자 정의 함수 완성 : 카이제곱 검정 : 두 변수(그룹)이 독립(귀무가설 참)이면 나와야하는 예상값을 가지고, 실제값과 차이를 제곱한 것을  /  다시 예상값으로 나눠준 뒤,각 요소들을 다 더해주기.####
# sum(  (실제값 - 예상값)^2 / 예상값  )
chisq <- function(Obs){
   Expected <- outer(rowSums(Obs), colSums(Obs)) / sum(Obs)
   return( sum( (Obs - Expected)^2 / Expected ))
}

chisq(data) # [1] 9.132947


#### 5. 카이제곱 검정 결과가 유의미한지 알기 위해 p-value값 구하기 ####
# p-value : 전체 값 - pchisq( 카이제곱 검정 결과, 자유도 )
# 자유도 : n by m matrix에서는 (n-1)*(m-1)로 구한다.
# pchisq( chisq , 자유도 )는 R에서 기본제공되는 함수, 카이제곱 검정결과, 자유도를 대입하면 넓이(%)가 나온다.

1 - pchisq(9.132947, (2-1)*(2-1)) # 0.00251047

#*** p-value 값이 0.0025 로 0.05보다 작으므로 --> 귀무가설 거짓(=예상값과 실제값차이 많이 남 = 변수들 독립)이 유의미하다 라는 결론을 내릴 수 있다.
# > 귀무가설H0를 파기하고 독립x 차이가 있다. -> 대립(대체) 가설을 채택 함.


#### 6. 간단하게 존재하는 함수 ####

# Pearson's Chi-squared test with Yates' continuity correction
chisq.test(data) # X-squared = 8.2683, df = 1, p-value = 0.004034
# correction 이 들어가기 때문에, 원조 카이제곱 검정과 값이 차이난다.

#Pearson's Chi-squared test
chisq.test(data, correct = FALSE) # X-squared = 9.1329, df = 1, p-value = 0.00251

#### normal distribution ( mean=80, sd=10 ) ####
# 1. x의 범위 정하기 **** 많이 빼먹는다**** sd가 10이면, 평균 80좌우로 3~4배 왔다리 갔다리 면 충분하다.
x <- seq(40, 120, length = 300) # ***연속 정수는 c(40:120) 겠지만, 연속실수범위는 seq(from=,to=, by=증감도, length = 구간 개수 )
x
# 2. dnorm(구간속 x값, mean, sd) :  x구간 속 300개의 각 값들에 대한 정규분포 만들어주기
y <- dnorm(x, mean = 80, sd = 10)
# 3. 단순 plot(x, y)그리기
plot(x, y) # 동그라미들은 x에 대응하여 300개..
plot(x, y, type = "l") # 동그라미를 type="l"로 라인으로
plot(x, y, type = "l", col = "red") # 색도..

image

# plot(type="l") 대신 lines()함수로 바로 그릴 수 있다.
# sd 5
#lines(x, dnorm(x, mean = 80, sd = 5), col = "blue")

image


# 1. dnorm() : x범위에 대해 해당 정규분포의 <전체 분포>를 그릴 때 y값
# 2. pnorm() : x범위에 대해 해당 정규분포의 <넓이 = percentage>를 구할 때
#   - %는 왼쪽끝에서 시작한 영역이 반환됨. (lower.tail = TRUE 가 default)
# 3. qnorm() : 정규분포의 영역에 대해, x값(cutoff)를 구할 때
#   - %, 넓이를 인자로 넣을 땐, 1보다 작은 소수점으로 대입

# 4. rnorm() : 임의의 정규분포


#### 문제1. 65 ~ 75까지는 몇 확률(% ->pnorm, 넓이*100)에 해당할까? ####
# 참고) 정규분포의 일부영역을 그래프로 그리기
x_cf <- seq(65, 75, length = 200) # 해당영역 x범위 정하기
y_cf <- dnorm(x_cf, mean = 80, sd = 10) # y에 똑같은 정규분포 그리기
polygon( c(65, x_cf, 75), c(0, y_cf,0 ), col="gray") # polygon(c( 아래변 ), c(덮는 윗변), col="배경색")

image

# ***정규분포의 %, 넓이를 구하는 문제이므로 pnorm()을 사용한다.
# pnorm( %(넓이*100), mean, sd)
# 큰 면적 - 작은면적의 원리이다.

pnorm(75, mean = 80, sd = 10) # 0.308
pnorm(65, mean = 80, sd = 10) # 0.066
pnorm(75, mean = 80, sd = 10) - pnorm(65, mean = 80, sd = 10) # 0.2417



#### 문제2. x=92보다 클 때의 확률(%->pnorm)은?
# -> 92일의 pnorm을 구한 다음, 1에서 빼자.
pnorm(92, mean = 80, sd = 10) # 0.884
1 - pnorm(92, mean = 80, sd = 10) # 0.1150697
# *** 오른쪽끝에서 92까지의 면적을 구하고 싶다면 lower.tail = FALSE로 준다)
pnorm(92, mean = 80, sd = 10, lower.tail = FALSE) # 0.1150697



#### 문제3. x가 68보다 작을때의 확률은? ####
pnorm(68, mean = 80, sd = 10) # 0.115069


#### 문제4. 하위 30%를 잘라내는 cutoff( % -> x구하기 : qnorm)는?
# *** 정규분포 영역에 대한 -> x값을 구할때는 qnorm()을 사용한다.
# *** 첫번째 인자에서는 영역의 %-> /100 이므로 1보다 작은 소수점으로 넣어줘야한다.

qnorm(0.3, mean = 80, sd = 10) # 30% -> 0.3으로 대입할 것!**** : 74.75


#### 문제5. 하위 80% 자르는 지점은?
qnorm(0.8, mean = 80, sd= 10) # 88.41


#### 문제6. 중간 60%를 자르는 지점은?
# 하위20%, 상위20 **= 하위80% 을 찾는다...
qnorm(0.2, mean = 80, sd= 10) # 71.58
qnorm(0.8, mean = 80, sd= 10) # 88.41


#검산해보기*** 2개의 값이 대칭(하위20, 상위20)인가?
# 평균은 80에서 하위20%의 x값을 빼면,, 그 절대값이 똑같아야함.
80 - qnorm(0.2, mean = 80, sd= 10) # 8.416
80 - qnorm(0.8, mean = 80, sd= 10) # -8.416

strsplit( , split="") + paste( , collaspe ="")를 이용해 문자열 역순으로 반환하기


#### strsplit() - 결과는 [[1]] 리스트인 것 유의! ####
#*** 실제로 띄워쓰기가 있는 경우 많이 쓰인다.
strsplit("adfawwsfwwdsfwa", split="w") # 기준이되는 w는 사라진다.
# 띄워쓰기를 쪼개기g
strsplit("how are you?", split=" ")


# *** 모든 단어 쪼개기 , split="" ***
strsplit("how are you?", split="")
a <- strsplit("how are you?", split="")
a #a를 확인해보니, [[1]]형태의 리스트이다.****
class(a)


# 다시 합치기
paste(a) # ***strsplit()으로 쪼개면, list형태의 [[]]로 반환되기 때문에 바로 못붙힌다.***
class(a[[1]]) #character 벡터
paste(a[[1]]) # 붙은 것 같으나 따옴표로 연결되어있다.
paste(a[[1]], collapse = "") # strsplit()으로 쪼갠 문자열 리스트는, [[1]]해도 바로 안붙고, collapse인자로 큰따옴표를 붕괴시켜야 제대로 붙는다.


#### 실전 ####
# 글자가 앞뒤가 바뀌도록 하는 함수 만들기***
# 1. strsplit( , split = "") 로 모든 단어 다 쪼개기
splited <- strsplit("I love you, daisy Kim!", split="")

# 2. 쪼개진 단어들 역순시키기기
#  - ***원소들의 인덱싱을 역순으로 해주면 된다.***
length(splited[[1]]) # 리스트 속 쪼개진 문자열 데이터의 개수
#  - ***만약 원래 String을 가져올 수 있다면 nchar(string)으로 하면된다.
#  - 끝:1로 역순으로 인덱싱하여 역순으로 바꾸자.
splited[[1]] [ length(splited[[1]]) : 1]
reversed <- splited[[1]] [ length(splited[[1]]) : 1]
# 3. paste(, collapse=="")로 쪼개진 단어들 붙히자.
paste(reversed, collapse = "")



#### 글자 역순으로 바꾸는 사용자 함수 정의 ####
reverse_char <- function(string){
   splited <- strsplit(string, split="")
   # 원본 문자열전체를 string으로 알고 있으니, nchar(string)만 해주면, 쪼개진 단어의 끝 번호를 알 수 있다.
   reversed <- splited[[1]] [nchar(string):1]
   result <- paste(reversed, collapse = "")
   return(result) # return과 for 다음에 바로 ()가 필요하다!***
}


reverse_char("안녕하세요")
reverse_char("how are you?")



strsplit( , split=" ") + paste( , collaspe =" ")를 이용해 단어 역순(reverse)으로 반환하기

# 지난시간 모든 글자 쪼개기
a <- strsplit("how are you?", split="") #split = ""를 통해 모든글자 쪼개기


#### 단어를 역순으로 배열하기 ####
# 1. 단어별로 쪼개기
splited <- strsplit("how are you?", split=" ") #split = " "를 통해 단어별로 쪼개기
splited


# 2. 쪼개진 단어들의 갯수 끝번호 : 1  -> 반대로 인덱싱하여 역순으로 배열하기
reversed <- splited[[1]] [length(w[[1]]) : 1]
reversed


# 3. 합치기
paste(reversed, collapse = " ") # collapse = " "를 통해 단어별로 합치기


# 4. 함수로 만들기
reverse_word <- function(string){
   splited <- strsplit(string, split=" ")
   reversed <- splited[[1]] [length(splited[[1]]) : 1] # 글자쪼개기와 다르게 nchar(string)는 글자 총 몇개 <---> 여기서는 쪼개진 단어가 몇개의 데이터인지 알아야한다.
   return(paste(reversed, collapse = " "))
}


reverse_word("안녕 하세용!")

+ Recent posts