한의대 생활/└ R studio 통계적 분석1
- 16. lm(y~X)의 결과를 summary()를 통해 Linear regression Model 판단하고, plot()+abline()+point()그려보기 2019.01.03
- 15. matrix 판별식 det(A), 역행렬 solve(A)와 사용자 정의함수 2019.01.02
- 14. R markdown 사용법과 matrix() 기초 연습 2019.01.02
- 13. [ SQL ] MySQL 설치 및 RMySQL - dbConnect(), dbGetQuery(), dbDisconnect() / gsub()로 특정문자열 치환 2019.01.02
- 12. if{} else if{} else{}로 aggregate(특정칼럼, by=list(기준칼럼), 통계) 흉내내기 + 조건별 문자열 출력해주기 2019.01.01
- 11. aggregate(통계구할칼럼인덱싱, by=list(기준칼럼인덱싱1, 2,,,), 통계함수) 로 기준1, 2에 따른 특정칼럼의 통계값 구하기 / summary() + MASS패키지의 Aids2 데이터 2019.01.01
- 10. [ hypergeometric & binomial distribution ] dhyper(n, a,b, m) --- 추출size(m 중 n)와 성공횟수(n/m) 유지 & 전체size를 늘이면 ---> dbinom(n, m, p)에 가까워진다! 2018.12.31
- 9. tapply()을 통한 --> 기준(범주)칼럼의 값 별로 특정칼럼의 통계(sum, mean) 빠르게 구하기 (기존방식과 비교) 2018.12.31
- 8. [ Chi-Square ] 카이제곱 검정 - 사용자 정의함수와 chisq.test( matrix , correct=FALSE) 2018.12.31
- 7. [ Norm distribution ] 문제 - seq()+*dnorm()-그리기 / *pnorm()-x로 넓이 / *qnorm()-넓이로 x 2018.12.31
- 6. 문자열4 - strsplit( , split=""/" ") + paste( , collaspe =""/" ")를 이용해 문자열 / 단어 역순(reverse)으로 반환하기 2018.12.31
- 5. 문자열 3 - grep() : 특정문자열 -> *index or *문자열전체 반환 // stringr패키지 - str_count() with sum() -> 문자열전체에 대한 *특정문자열 포함개수 반환 2018.12.31
- 4. 문자열2 - paste()로 붙히기, which() - 가장 긴 값 찾기 2018.12.30
- 3. 문자열1 - character()에 대해 2018.12.30
- 2. tidyr(데이터 정리함수 3개) -> dplyr(필터함수 1개) + 파이프라인 사용법 2018.12.30
16. lm(y~X)의 결과를 summary()를 통해 Linear regression Model 판단하고, plot()+abline()+point()그려보기
year <- c(2000:2004)
year
value <- c(2.3, 3.2, 5.6, 5.4, 5.8) # 약간 선형으로 증가하게 만듬
# 기본 plot
plot(year, value)
# 대략적인 2005년도 값 추정하기 위해 선을 그리는데, 오차범위(잔차, residual)가 존재한다
# 각 점들과 선의 오차가 최소로 되도록 선을 긋는 것을 선형모델 Linear Regression model이라고 한다.
lm(value ~ year) # y ~ X
# 오차를 최소로하는 선을 긋는 lm()의 결과값은 절편과 기울기 +@(가 생김
fit <- lm(value ~ year)
fit
# linear regression model의 선을 그래프에 추가
abline(fit)
# y가 잘리니까 그래프의 y축 범위 늘려주기
plot(year, value,
ylim = c(0, 10))
# 선 추가 + 색 추가
abline(fit, col="red")
# *** 선<-> 점들 간에 차이인 잔차(residual)을 최소로 하는 선이 그어진다. ***
# *** lm()결과에서 성분들 뽑아보기***
fit$coefficients[[1]] # 1) 절편값
fit$coefficients[[2]] # 2) 기울기
fit$residuals # 3) x 5개의 y값에 대한 선들과의 잔차(y-선)
# *** lm()이후 결과값 fit에 대해 summary()를 하는 버릇을 가지자 ***
# *** 선형 모델이 말이 된다/안된다를 판단하는 대략 기준
# 1) summary()시 *가 찍혀있는지/없는지 2) p-value(선형모델이 우연히 나올 확률*)가 0.05이하인지
summary(fit)
#### 2005 - 100값으로 확 증가하는 1개의 점 추가하고 fit결과를 summary()해보기 ####
year <- c(2000:2005)
value <- c(2.3, 3.2, 5.6, 5.4, 5.8, 100) # 약간 선형으로 증가하게 만듬
fit <- lm(value ~ year)
plot(year, value,
ylim = c(0, 150))
abline(fit, col="red")
summary(fit) # 1) *가 없어지고 2) p-value가 0.05보다 훨씬 큰 0.13이 나옴. --> 데이터를 설명 잘 못하는 모델이다.
#### 더 직선에 가깝게 y값을 조절해보자.
year <- c(2000:2004)
value <- c(2.3, 3.2, 4.9, 5.4, 5.8) # 2003의 값을 더욱 선형에 가깝게 조절
fit <- lm(value ~ year)
plot(year, value,
ylim = c(0, 10))
abline(fit, col="red")
summary(fit) # 1) ** 2개 2) p-value : 0.006 => 이 선형모델은 우연x 데이터를 잘 설명하는 모델이며 받아들일 수 있다.
# ***받아들인 모델을 가지고 다음 값 추정해보기****
# 선형이므로 fit의 결과값 2개인 절편/기울기로 선형식을 만들어 대입한다( y = ax+b)
predict <- fit$coefficients[[2]] * (2015) + fit$coefficients[[1]]
plot(year, value,
ylim = c(0, 20),
xlim = c(2000, 2020))
abline(fit, col="red")
'한의대 생활 > └ R studio 통계적 분석1' 카테고리의 다른 글
15. matrix 판별식 det(A), 역행렬 solve(A)와 사용자 정의함수
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 studio 통계적 분석1' 카테고리의 다른 글
14. R markdown 사용법과 matrix() 기초 연습
R markdown
- 패키지 설치
- 아래와 같이 생성
- title + HTML선택만 해준다. - 아래 스크린샷 부분은 설치 방법 & 주석이므로 제거한다.
- R코드는 ```{r} 으로 시작 ```으로 끝을 낸다.
- 기본 제공되어있는 코드로 상단의 Knit - Knit to HTML를 눌러보자.
- 저장시 아무 확장자도 안주어야지 .Rmd로 저장된다. html로 하면 안됨. -. 알아서 .html도 생성된다.
- 생성된 R markdown - html양식
- echo = FALSE 라는 인자가 들어간 부분은 -> 코드( plot(pressure) )없이 결과값만 뜬다.
연습해보기
연습한 Rmarkdown.html 코드 복사해넣기
R matrix practiec
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
'한의대 생활 > └ R studio 통계적 분석1' 카테고리의 다른 글
13. [ SQL ] MySQL 설치 및 RMySQL - dbConnect(), dbGetQuery(), dbDisconnect() / gsub()로 특정문자열 치환
#### 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;
# *** classicmodel 이라는 db에서 table 중 employees table을 불러올 것임 : use classicmodels; > show tables; > select * from employees;
#### 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가 돌아가는 상태여야 한다.
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)
'한의대 생활 > └ R studio 통계적 분석1' 카테고리의 다른 글
12. if{} else if{} else{}로 aggregate(특정칼럼, by=list(기준칼럼), 통계) 흉내내기 + 조건별 문자열 출력해주기
# 데이터 준비
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)
'한의대 생활 > └ R studio 통계적 분석1' 카테고리의 다른 글
11. aggregate(통계구할칼럼인덱싱, by=list(기준칼럼인덱싱1, 2,,,), 통계함수) 로 기준1, 2에 따른 특정칼럼의 통계값 구하기 / summary() + MASS패키지의 Aids2 데이터
#### "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)
'한의대 생활 > └ R studio 통계적 분석1' 카테고리의 다른 글
10. [ hypergeometric & binomial distribution ] dhyper(n, a,b, m) --- 추출size(m 중 n)와 성공횟수(n/m) 유지 & 전체size를 늘이면 ---> dbinom(n, m, p)에 가까워진다!
#### 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
# ***100개의 확률이 어디로 근접하는지 plot으로 확인하자
# approx[1]은 확률이 0이라서,, 그래프가 안그려지더라...? 2부터..
plot(approx[2:100])
# *** 초기하분포 확률 plot에다가 이항분포의 확률을 선으로 그려주자.
# *abline( h = 값) - 직선을 그려주는데 h(수평선)을 그려준다.
abline(h = dbinom(3, 10, 0.4), col="red")
# 값 차이
approx - dbinom(3, 10, 0.4) # 마지막 100번째엔 0.0005 차이
'한의대 생활 > └ R studio 통계적 분석1' 카테고리의 다른 글
9. tapply()을 통한 --> 기준(범주)칼럼의 값 별로 특정칼럼의 통계(sum, mean) 빠르게 구하기 (기존방식과 비교)
기존 방식
기준칼럼의 각 값별로 인덱싱 -> 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)
'한의대 생활 > └ R studio 통계적 분석1' 카테고리의 다른 글
8. [ Chi-Square ] 카이제곱 검정 - 사용자 정의함수와 chisq.test( matrix , correct=FALSE)
대충 정리한 것.
두 변수(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)와 동일
# 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
'한의대 생활 > └ R studio 통계적 분석1' 카테고리의 다른 글
7. [ Norm distribution ] 문제 - seq()+*dnorm()-그리기 / *pnorm()-x로 넓이 / *qnorm()-넓이로 x
#### 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") # 색도..
# plot(type="l") 대신 lines()함수로 바로 그릴 수 있다.
# sd 5
#lines(x, dnorm(x, mean = 80, sd = 5), col = "blue")
# 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="배경색")
# ***정규분포의 %, 넓이를 구하는 문제이므로 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
'한의대 생활 > └ R studio 통계적 분석1' 카테고리의 다른 글
6. 문자열4 - strsplit( , split=""/" ") + paste( , collaspe =""/" ")를 이용해 문자열 / 단어 역순(reverse)으로 반환하기
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("안녕 하세용!")
'한의대 생활 > └ R studio 통계적 분석1' 카테고리의 다른 글
5. 문자열 3 - grep() : 특정문자열 -> *index or *문자열전체 반환 // stringr패키지 - str_count() with sum() -> 문자열전체에 대한 *특정문자열 포함개수 반환
mtcars
cars <- rownames(mtcars)
which(nchar(cars) == max(nchar(cars)))
cars[which(nchar(cars) == max(nchar(cars)))]
#### grep() ####
# 특정 문자열을 포함하는 데이터의 < 1) index 2) <문자열 전체>(value=TRUE)>를 반환한다.
# *** 주소에서 성북동을 포함한 주소를 검색하는 경우 등에서 사용된다.
# grep("문자열", data)
# grep("문자열", data, value = TRUE)
# ***대소문자 구분해버리므로 둘다 불러오고 싶다면 ***
# 1) grep("[vV]", data, value = TRUE)
# 2) 데이터 자체를 소문자나 대문자로 변환시킨 뒤 -> grep()을 쓴다.
# ***my) cars %in% c("z") 는 포함관계가 아니라, 특정값 자체를 <or연산 : | | |>여러개 대신 연속(1:3)or이산(c(1, 3, 5)으로 쉽게 필터링에 쓸 수 있다. http://nittaku.tistory.com/352?category=764233
cars
grep("z", cars) # 1 2 --> 1번째 데이터, 2번째 데이터에서 가진다.
grep("z", cars, value = TRUE) # 실제 전체문자열을 보려면 value = TRUE 인자를 넣어준다.
grep("rd", cars, value = TRUE)
# ***대소문자 모두 포함된 문자열을 가져올 경우***
grep("[vV]", cars, value = TRUE)
# ***데이터 자체를 대문자 or 소문자로 바꾼 뒤 grep()하기 ****
grep("v", tolower(cars), value = TRUE)
grep("toyota", cars, value = TRUE )
grep("toyota", tolower(cars), value = TRUE )
grep("TOYOTA", toupper(cars), value = TRUE )
#### stringr 패키지 ####
#### ...L 1) str_count(df, "문자열") ####
# 문자열데이터 각각에 대해, 특정 문자열을 <몇개> 포함하고 있는지를 각 문자열데이터에 대한 벡터 반환해준다.
# *** 전체 자동차 리스트에서 sum()을 씌워, 해당 모델이 몇개 포함되어있는지 알 수 있다. ***
# *** 조씨 성을 가진 사람이 <몇명>인지 알 수 있다.
# str_count(df, "문자열")
# grep("문자열", df, value = TRUE)와는 인자가 순서가 다르다.
install.packages("stringr")
library(stringr)
cars
str_count(cars, "t") # (df, "문자열") -> 0 0 1 1 3 1 1 1 식으로 문자열 포함개수를 알려줌
str_count(cars, "o")
# 실전 - sum()을 마지막에 씌워, 전체 문자열데이터에서, 해당 브랜드 자동차모델이 몇개 가지고 있는지 알 수 있다.
str_count(toupper(cars), "TOYOTA") # 2개 발견
sum( str_count(toupper(cars), "TOYOTA") )
'한의대 생활 > └ R studio 통계적 분석1' 카테고리의 다른 글
7. [ Norm distribution ] 문제 - seq()+*dnorm()-그리기 / *pnorm()-x로 넓이 / *qnorm()-넓이로 x (0) | 2018.12.31 |
---|---|
6. 문자열4 - strsplit( , split=""/" ") + paste( , collaspe =""/" ")를 이용해 문자열 / 단어 역순(reverse)으로 반환하기 (0) | 2018.12.31 |
4. 문자열2 - paste()로 붙히기, which() - 가장 긴 값 찾기 (0) | 2018.12.30 |
3. 문자열1 - character()에 대해 (0) | 2018.12.30 |
2. tidyr(데이터 정리함수 3개) -> dplyr(필터함수 1개) + 파이프라인 사용법 (0) | 2018.12.30 |
4. 문자열2 - paste()로 붙히기, which() - 가장 긴 값 찾기
#### paste(,sep=" "), paste0( ) 함수 - 깨진 데이터, 끊긴 데이터를 합칠 때 ####
hi <-paste("hi", "Jack") # paste()함수는 붙혀넣기다.
# 끊킨 데이터를 붙혀주는 2가지 함수
# my) 구분자를 넣어서 붙히고 싶다면 paste(), 구분자 없이 바로 붙히려면 paste0()
paste("jac", "k") # "jac k" ***paste()의 sep의 default는 " " 띄워쓰기 1칸이 있다.
paste("jac", "k", sep = "") # "jack"
paste0("jac", "k") # "jack"
paste("Hi", "jack", sep = ", ") # "Hi, jack"
#### 실전 응용 ####
#*** 1-1반부터 1-10반까지 붙혀넣어보자.
# 만약 모른다면,,,
c("1-1", "1-2", "1-3") #...
#my)...
global_object <<- character(10) # 전역변수는 생성시만 <<- 함수안이라도 대입은 <-
for(n in 1:10) {
global_object[n] <- paste0("1-", as.character(n))
}
global_object
#### *** paste() + 연속변수로 생성하면 ####
# "1"고정 / sep= "-" 구분자 / 나머지는 1:10까지 연속변수 생성
paste("1", 1:10, sep="-" )
# 따옴표를 제거하고 출력하기
a <- paste("The value of 'pi' is ", pi, ", endless!")
noquote(a) # 문자열에서 따옴표 제거하고 출력방법 1 ***
print(a, quote=FALSE) # 문자열에서 따옴표 제거하고 출력방법 1 ***
# rownames() 데이터에서 행이름만 가져오기
data("mtcars")
rownames(mtcars) # colnames는 자주썼었다.
#my) 행을 쉽게 보는 방법 t()
t(t(rownames(mtcars)))
colnames(mtcars) # colnames()
#nchar() 문자열 길이 확인( 문자열 벡터도 한번에 확인가능 )
nchar("조재성") # nchar() 문자열 길이를 벡터로 나타내준다. -> 3
length("조재성") # length() 데이터(문자열 벡터)의 개수다. -> 1
nchar(rownames(mtcars))
# which( 조건문 )로 가장 긴 이름 찾기 ********
# - which( 칼럼인덱싱 조건문 )으로 해당row를 반환하여 확인했었다. http://nittaku.tistory.com/336
# - which(sample[,1] == "ccd")
# 1) ncha()를 이용하여 문자열 길이를 벡터로 반환받기
# 2) nchar() == max( nchar() )를 조건문으로 해서
# 2) 문자열길이 벡터에 which( 조건문 )를 써서 가장 큰 값 받환하기
cars <- rownames(mtcars)
which( nchar(cars) == max(nchar(cars)) ) #16
cars[16]
# 한 문장으로 뽑아내기 - 인덱싱자리에서 넣기
cars[ which( nchar(cars) == max(nchar(cars)) )] # 1차원...
'한의대 생활 > └ R studio 통계적 분석1' 카테고리의 다른 글
3. 문자열1 - character()에 대해
x <- 'what is your name?'
x <- "what's your name?" #작은따옴표를 안에 쓰려면 큰따옴표로
# character() 인자에 빈값을 넣으면?
y <- character() # my) character()를 사용하면 문자열 1차원 벡터가 생성
y #***character(0) = 빈값의 character 벡터라고 뜬다.
class(y) # 속성은 character
length(y) #길이(=데이터의 개수) 0인 character
# 케릭터 객체에 ""을 넣으면?
y2<-""
y2 # ""
class(y2) #속성은 character
length(y2) # ***length는 문자열 데이터의 개수... 문자열 길이 아님!***
length("1") # "1"도 길이가 1이지만, ""도 길이가 1이다!! length는 문자열의 데이터의 개수 <---> nchar() 문자열 길이
y3 <- c("e", "12", "2") # 문자임
y4 <- character(10)
y4 # *** 큰따옴표가 10쌍이다.
# 3번째에다가 값을 넣어보자.
y4[3] <- "third"
y4 # "" "" "third" "" ...
# 10개까지만 있는 문자열 벡터에다가 12번째에 값을 넣어보면?
y4[12] <- "twelveth"
y4 # ***11번째에는 NA(결측치)가 차고, 12번째에 값이 들어간다
length(y4) # 길이는 12가 된다.
y4[11] <- "11"
y4
# 문자열인지 확인하기
n = 3
m = "3"
# 아래 부분이 필요한 것은 함수 속 if문...에서... 문자열/숫자 확인할 때!
is.character(n) # FALSE
is.character(m) # TRUE
class(n)
class(m)
#아래부분이 필요한 것은, 엑셀 등에서 가져온 자료가 숫자가 아니라 문자열일 경우 바꿔주기
n2 = as.character(n) # 3 -> "3"
class(n2)
# 문자열은 1차원 벡터에 있어서, 자료형이 우선순위
t <- c(1:5) # 1, 2, 3, 4, 5
# 1차원 벡터에 있어서, 하나라도 문자열이 들어가면 모두 따옴표가 붙어 문자열이 되어버린다.
t2 <- c(1:5, "a")
t2 # "1", "2", "3", "4", "5", "a"
# 숫자 + logical을 섞는다면?
t3 <- c(1:5, TRUE, FALSE)
t3 # ***logical도 컴퓨터는 1, 0으로 알아듣는 숫자다
class(t3)
t4 <- c(1:5, TRUE, FALSE, "a")
t4 #문자열이 하나라도 섞이면 전부다 따옴표가 붙고, 문자열이 된다.
#***이 때, TRUE는 "1"이 아니라 "TRUE"로 바뀐다.
df1 <- data.frame( n = c(1:5), #df는 각 요소의 개수가 딱맞는 사각형이어야한다.
letters = c("a", "b", "23", "1", "24") )
df1
# **** data.frame에서는 문자열을 "따옴표"로 표시해주지 않는다! ****
# ***data.frame의 형식을 문자열 따옴표를 보는 방법은 str()을 이용하는 것이다 ***
str(df1) # factor도 문자열을 포함한다?
df2 <- data.frame( n = c(1:4, "a"), #df는 각 요소의 개수가 딱맞는 사각형이어야한다.
letters = c("a", "b", "23", "1", "24") )
str(df2) # data.frame도 칼럼별로 문자열이 자료형 우선순위를 가진다.
# my)***
df2 <- data.frame( n = c(1:4, "a"), #df는 각 요소의 개수가 딱맞는 사각형이어야한다.
letters = c("a", "b", "23", "1", "24"),
stringsAsFactors = FALSE)
# 이전에 배운 sapply()로 칼럼별로 class를 본다.
apply(df2, MARGIN = 2, FUN = "class")
sapply(df2, "class")
'한의대 생활 > └ R studio 통계적 분석1' 카테고리의 다른 글
2. tidyr(데이터 정리함수 3개) -> dplyr(필터함수 1개) + 파이프라인 사용법
install.packages("tidyr") # 정리할 때 좋은 패키지
install.packages("dplyr")# 자료를 빨리 찾아볼 때 좋은 패키지 (필터링 패키지)
library(dplyr)
# 데이터 준비
# 3가족이 사는데, f여자, m남자에 대한 이름과 나이 정보
member = data.frame(family = c(1, 2, 3),
namef = c("a", "b", "c"),
agef = c(30, 40, 23),
namem = c("d", "e","f"),
agem = c(44, 53, 25))
member
# data.frame의 현재형태는 각 가족에 대해서 보기 편할 수 도 있다.
# 예를 들어, 1번 가족에 a(30세), d(44세)가 있다. 이런식이다.
# 하지만, 데이터 분석에 있어서는 안좋다.
# 예를 들어, 여자멤버는 누가 있고, 나이에 따른 분포 등을 알기 어렵다
# 즉, 그래프를 그리기 쉽지 않다.
### 문제 : 데이터에서 namef, namem이 아닌 f/m를 따로 표시해서 알아보기 ###
#### 1. tidyr(타이디 r)을 이용해서 정리하기 ####
library(tidyr)
#### ...L 1) gather() ####
# 여러칼럼들을 칼럼들을 --> 1개의 칼럼key - value 값을 형태로 모아주는 함수
# gather( df, key*칼럼명 모을칼럼명, value*모을값의 칼럼명, 식별칼럼제외 모을 칼럼범위a:b)
# *** 이 때, 식별칼럼에 해당하는 family칼럼은 제외하고 모아준다. 만약 식별칼럼까지 모아버리면, 모으기전 같은 라인에 있던 이름-나이 의 연관성이 사라져버린다.
# *** reshape2패키지의 melt()와 매우 유사함.(http://nittaku.tistory.com/349)
# gather(membe(df), key(칼럼명모은 칼럼명), value(값 모은 칼럼명), family:agem) : 식별칼럼family까지 모으면, 모이기전의 값들이 연관성이 없어져버린다.
# ex> 1-namef-a / 1-agef-30 ==> namef-a 와 agef-30의 이름과 나이의 연관성이 사라져버림
gather(member, key, value, namef:agem)
a <- gather(member, key, value, namef:agem)
#### ...L 2) separate() ####
# 특정 칼럼의 값 -> 2개로 쪼개면서 2개의 칼럼 생성
# - gater로 모아진 데이터를 이용해서, 특정칼럼의 값을 쪼갠다.
# separte(값을 쪼갤df, 쪼갤칼럼명, c("쪼갠칼럼1", "쪼갠칼럼2"), 쪼갠위치)
b <- separate(a, key, c("variable", "type"), -1) # 뒤에서
#### ...L 3) spread() ####
# key-value형태의 칼럼을 --> key값을 기준으로 여러칼럼으로 생성 + value은 각각에 따라붙음
# ***reshape2의 dcast()와 비슷한 듯 : http://nittaku.tistory.com/349
# 여러칼럼들을 모아서 필요한 처리이후, 다시 name과 age를 분리하기
# spread(칼럼명/ 값 칼럼을 <칼럼명의 값의 이름으로> 2개칼럼으로 나눌df, 나눌 칼럼명, 따라붙을 값 칼럼)
new <- spread(b, variable, value)
### *** my) gather()와 spread()는 값은 따라이동하기만 하고, 칼럼을 뭉치고/나눈다. ***
#### 2. dplyr패키지의 filter()함수로 여자만 필터링하기 ####
## dyplr패키지의 filter함수는 벡터연산의 [df$칼럼명 , ]과 달리
## filter(df, 칼럼명 == )으로 바로 인덱싱 but 자동완성x http://nittaku.tistory.com/352
filter(new, type == "f")
filter(new, age >= 30)
#### 3. 만약, tidyr로 정리한 데이터가 아니라면? ####
# (1) select( df, 가져올칼럼1, 가져올칼럼2, 가져올칼럼3)함수를 통해,
# df에서 f붙은 특정칼럼들만 가져온다.
select(member, family, namef, agef)
# (2) 벡터연산[,]을 통해 열만 인덱싱해준다.
member[,c("family", "namef", "agef")]
# 그러나 특정나이 이상인 모든 사람들을 가져오게할 때.. 쉽지가 않다.
# agef, agem 칼럼이 2개이기 때문...
#### 4. 파이프라인(%>%)을 통한 tidyr 함수3개 연속 사용하기 ####
# 파이프라인을 사용할 때는, 아래와 같은 형식이며
# 각 함수에서 df는 생략된다.
new2 <- member %>%
gather(key, value, namef:agem) %>% #칼럼들을 key-value로뭉치기
separate(key, c("variable", "type"), -1) %>% #값을 2개 칼럼으로 나누기
spread(variable, value) #key-value를 key값별로 칼럼나누
new2