R에서 제공하는 분포 관련 함수

density function of dist.

- d### (x,  ...<parameters>...)

 

distribution function of dist. 

- p###(q, ...<parameters>...)   # = P(X <= q)

- q###(p, ...<parameters>...)   # p = P(X <= x) >>> {P(X <= x)}^(-1)

 

 

 

이산확률분포 

 

이항분포

## 이항분포 - pmf 활용 ----
n = 15
p = 0.2
x = 0:10

y1 = dbinom(x, n, p) ; y1
plot(x, y1, type = "h", lwd = 3, col = "blue4")

## 이항분포 - cdf 활용 ----
y2 = pbinom(x, n, p) ; y2
plot(x, y2, type = "h", lwd = 3, col = "tomato")
plot(x, y2, type = "s", lwd = 3, col = "tomato")

## 이항분포 - check qbinom value ----
x; y2
qbinom(y2[2], n, p) == x[2]

 

 

포아송분포

## 포아송 분포 - pmf 활용 ----
lam = 2.5
x = 0:10
y1 = dpois(x, lam)

plot(x, y1, type = "h", lwd = 3, col = "blue4")


## 포아송 분포 - cdf 활용 ----
y2 = ppois(x, lam)
plot(x, y2, type = "h", lwd = 3, col = "tomato")
plot(x, y2, type = "s", lwd = 3, col = "tomato")

## 포아송 분포 - 값 찾기 ----
qpois(0.3456, lam)

 

 

 

연속확률분포

 

정규분포

## 정규분포 - pdf 활용 ----
mu = 0
sig = 1
x = seq(-5, 5, length = 20)

y2 = dnorm(x, mu, sig)
plot(x, y2, type = "h", lwd = 3, col = "blue4")

## 정규분포 - cdf 활용 ----
y3 = pnorm(x, mu, sig)
plot(x, y3, type = "s", lwd = 3, col = "tomato")

## 정규분포 - 값 찾기 ----
qnorm(y3, mu, sig) < qnorm(0.7, mu, sig)

 

 

t-분포

## t-분포 - pdf 활용 ----
df1 = 5
x = seq(-5, 5, length = 20)

y1 = dt(x, df1)
plot(x, y1, type = "h", lwd = 3, col = "blue4")

## t-분포 - cdf 활용 ----
y2 = pt(x, df1)
plot(x, y3, type = 's', lwd = 3, col = "tomato")

## t=분포 - 값 찾기 ----
qt(0.2, df1)

 

 

카이제곱분포

## 카이제곱분포 - pdf 활용 ----
df2 = 7
x = seq(0,30, length = 20)

y1 = dchisq(x, df2)
plot(x, y1, type = "h", lwd = 3, col = "blue4")

## 카이제곱분포 - cdf 활용 ----
y2 = pchisq(x, df2)
plot(x, y2, type = "s", lwd = 3, col = "tomato")


## 카이제곱분포 - 값 찾기 ----
qchisq(0.65, df1) + qchisq(0.65, df2)

이산확률분포

 

이산균등분포

> n개의 불연속적인 값을 가지는 확률변수 X가 아래와 같은 pmf를 가질 때 이산균등분포를 따른다고 하고, 

> X~U(a,b) 혹은 X~unif(a,b)로 표기함.

 

p(x) = 1/n , x = a, a+1, .... ,b 

## 이산균등분포 (Discrete uniform distribution) ----
n = 10
p = 1/n
x = 1:n
p.x = rep(p, n)
plot(x, p.x, xlim = c(1,n), ylim = c(0,1))

 

 

 

베르누이 시행

> 결과가 오직 두 가지 결과만을 가지고 성공할 확률이 일정한 실험

 

이항분포 

> 이항실험에 대해서 n번 시행 중 꼭 x번의 성공할 확률

> 베르누이 시행을 n회 시행했을 때 나오는 총 성공 횟수를 확률변수 X라고 하면, x는 이항분포를 따르며,

> X~B(n,p) 혹은 X~bin(n,p)로 표기함. 

## 이항분포 (Binomial distribution) ----
n = 10
p = 1/5
x = 1:n
p.x = choose(n,x)*p^x*(1-p)^(n-x)  # nCx
plot(x, p.x,
     xlim = c(1,n),
     ylim = c(0,1),
     main = "Binomial Dist.",
     col = "red")

 

 

포아송분포

> 일정한 구간에서 특정 사건이 일어나는 건수에 대한 분포 

> 조건

1. 주어진 구간에서 사건의 평균 발생횟수는 구간의 시작점과 관계가 없고 구간의 길이에만 영향을 받음.

2. 랜덤 발생: 한 순간에 2회 이상의 사건이 발생할 확률은 거의 0에 가까움.

3. 독립적으로 발생: 한 구간에서 사건의 횟수는 겹치지 않는 다른 구간에서 발생하는 사건의 횟수에 영향을 받지 않음. 

> 예) 일주일 동안(구간) 어느 고속도로에서 발생하는 교통사고 건수(특정 사건이 일어나는 건수) 

 

## 포아송 분포 (Poisson distribution) ----
n = 100
mu = 15
x = 0:n 
p.x = (exp(1)^(-mu)*mu^x)/factorial(x)
plot(x, p.x, xlim = c(1,n), ylim = c(0,1),
     main = "Poisson dist.", col = "blue",
     pch = 20)

 

기하분포

1.

> 특정 사건이 발생할 확률이 p로 일정할 때 해당 사건이 발생할 때까지 시행한 횟수를 확률변수 X라고 하자.

> 이때 x번째에 사건이 발생할 확률은 

> p(x) = (1-p)^(x-1) * p     x = 0, 1, .....

 

2. 

> 특정 사건이 발생할 확률이 p로 일정할 때 해당 사건이 발생할 때까지 실패한 횟수를 확률변수 X라고 하자.

> 이때 x번 실패 후 사건이 발생할 확률은 

> p(x) = (1-p)^x*p        x = 0, 1, .........

 

## 기하분포 (Geometric distribution)
n = 100
p = 1/3
x = 0:n
p.x = (1-p)^(x-1)*p
plot(x, p.x, xlim = c(0,n), ylim = c(0,1),
     main = "Geometric Dist.", col = "grey", pch = 20)

 

 

 

연속확률분포

 

연속균등분포 

> 구간 (a,b)에 있는 값을 가지는 확률변수 X가 아래와 같은 pdf(probability density function)를 가질 때 연속 균등 분포를 따른다고 하고, X~U(a,b) 혹은 X~unif(a,b)로 표기함.

p(x) = 1/(b-a) # x는 a,b 구간에 속해있다.

 

+ 연속형 분포의 그래프 그리기 

이산형과 달리 연속형은 'continuous'한 직선 혹은 곡선으로 표현 

 - 이산형 분포 그리기에서는 정의역 값을 vector로 묶어 지정하는 식으로 구현 가능

 - 이산형과 달리 연속형의 변수 값은 '구간' 형태

 

정의역 x의 구간과 x가 포함된 함수/표현식(expression)을 설정해주면 직/곡선을 그려주는 함수 활용

 - curve(expr, from = Null, to = Null, ...)

 -- expr에 x가 포함된 함수의 표현식을 설정 

 -- from,to에 각각 구간의 시작점과 끝점을 설정

 -- 기타 plot, hist에서 쓰는 옵션 지정 가능 

 

# X ~ U (0, 10)

n = 10
curve(1/n, from = 0, to = n, col = 2, lwd = 3)

 

그런데 이런 식으로 하면은 안됨. 위에서 curve의 expr에서 x가 포함된 함수의 표현식을 설정해서 나타내라고 했는데 그렇게 되지 않음. 이렇게 실행하면 다음과 같은 에러가 나옴.

 

 

따라서 이런 식으로 코드를 짜야함. 

curve(x/x/n, from = 0, to = n, col = 2, lwd = 3)

 

# X ~ U(2.3, 7.6)
n = 100
a = 2.3 
b = 7.6

curve(x/x/(b-a), a, b, col = 4, lwd = 3)

 

 

정규분포

> 대표적인 연속확률분포로 평균을 중심으로 좌우대칭이며 bell-shape을 가진 분포

## 정규분포 (normal distribution) ----
mu = 0 
var = 1^2

expr = (1/sqrt(2*pi*var))*exp(-(x-mu)^2/(2*var))
curve((1/sqrt(2*pi*var))*exp(-(x-mu)^2/(2*var)), -50, 50, col = 4, lwd = 3)

 

 

t - 분포 (Student's t - distribution)

> 평균 0 중심으로 좌우대칭인 bell-shape이며, 자유도 v에 의해 결정됨.

> 자유도가 커질수록 정규분포에 가까워지는 특징을 가짐. 

## t-분포 (Student's t - distribution) ----
nu = 3
curve((gamma((nu+1)/2))/sqrt(nu*pi)*gamma(nu/2)*(1+x^2/nu)^(-(nu+1)/2), -10, 10, col = 4, lwd = 3)

 

카이제곱분포 (Chi-square distribution)

> k개의 서로 독립인 (표준)정규확률변수를 제곱하여 합하여 얻은 변수의 분포

> 분포곡선은 수직축의 오른쪽에 위치하며, 모양은 자유도가 작은 경우에는 비대칭이고, 자유도가 증가함에 따라 대칭 모양에 가까워짐. 

## 카이제곱분포 (Chi-square distribution) ----
curve(1/(2^(nu/2)*gamma(nu/2))*x^((mu/2)-1)*exp(-(x/2)), 0, 10, col = 4, lwd = 3)

데이터를 시각화 하기 전에 파일 불러오기

setwd("C:\\Users\\user\\OneDrive - 경북대학교\\통계학과\\1-2\\R프로그래밍 및 실험")

#1
dat1 = read.csv("w7_2 csv.csv") # 띄어쓰기를 .으로 구분함
#2
dat1 = readr::read_csv("w7_2 csv.csv") # 띄어쓰기 있는 곳은 ``으로 묶어서 표기

1번
2번

 

시각화를 통해 데이터 분포 확인

 

히스토그램

hist(dat1$나이)

 

 

기호에 따라서 히스토그램을 더 보기 좋게 만들 수 있음.

hist(dat1$나이, main = "예제데이터의 나이(1)",
     xlab = "age", ylab = "빈도") 
     
# x축의 이름: xlab
# y축의 이름: ylab

 

 

hist(dat1$나이, main = "예제데이터의 나이(2)",
     xlab = "age", ylab = "빈도", breaks = 10)
     
# break를 통해 그래프를 더 나누어줄 수 있음.

 

 

 

 

산점도

plot(x = dat1$나이, y = dat1$`성취도 점수`) # 기본적인 형태
plot(x = dat1$나이, y = dat1$`성취도 점수`,
     main = "나이에 대한 성취도", xlab = "나이",
     ylab = "성취도") # 알아보기 쉽게 만듦.

plot (formula = `성취도 점수`~`나이`, data = dat1,
      main = "나이에 대한 성취도", xlab = "나이",
      ylab = "성취도") # 2번째와 똑같은 그래프인데, 형태가 다름.

 

 

plot(formula = `우울 점수`~`나이`, data = dat1,
     main = "나이에 대한 우울 점수", xlab = "나이",
     ylab = "우울 점수",
     col = c("red", "blue")[factor(성별)], cex = 1.5,
     pch = c(20, 18)[factor(성별)])
     
# col 색 변경 / pch 점 모양 / cex 점 크기

 

직선 추가하기

# y = a+bx
abline(a = -20, b = 1,
       col = "dark green", lty = "dotted", lwd = 2.0) 

# y = h
abline(h = 40, 
       col = "dark red", lty = "dotted", lwd = 2.0) 

# x = v
abline(v = 50,
       col = "dark blue", lty = "dotted", lwd = 2.0)

# 평활 직선
lines(stats::lowess(x = dat1$나이, y = dat1$`우울 점수`),
      col = "dark red")
      
h = horizontal line
v = vertical line

 

참고

 

지수평활법

가장 최근 데이터 가장 큰 가중치가 주어지고 시간이 지남에 따라(과거로 갈수록) 가중치가 기하학적으로 감소되는 가중치 이동 평균 예측 기법의 하나. 데이터들이 시간의 지수 함수에 따라 가중치를 가지므로 지수 평활법이라고 한다. 이 기법은 가장 최근의 예측 데이터와 주요 판매 데이터 간의 차이에 적합한 평활 상수를 사용함으로써 과거의 데이터를 유지할 필요성을 갖지 않는다. 이러한 접근 방법은 어떤 추세를 갖지 않거나 계절적인 패턴을 나타내는 데이터 또는 추세와 계절성을 모두 갖는 데이터에 사용될 수 있다.

[네이버 지식백과] 지수 평활법 [exponential smoothing, 指數平滑法] (IT용어사전, 한국정보통신기술협회)

정렬 (sorting)

- 일반적으로 정렬하는 변수는 수치형이거나 문자형

- 종류: 오름차순, 내림차순

- 숫자 > 영어 > 한글

- sort(<object>, ...)

- 예시

c("a", "b", "가", "나", "1", "2")
vec = sample(c("a","b","가","나","1","2"), 10, replace = T)

sort(vec) # ascending
sort(vec, decreasing = T) # descending

sort(c("a", "b", NA), na.last = NA)
sort(c("a", "b", NA), na.last = TRUE) 
# NA의 값이 제일 뒤에 출력
sort(c("a", "b", NA), na.last = F) 
# NA의 값이 앞에서 출력

 

 

 

그룹화(grouping)

- 데이터 가공/전처리 과정 중 하나로 어떠한 특성을 기준으로 자료를 여러 개로 분할하는 작업

- 조건 활용

data(InsectSprays)
unique(InsectSprays$spray)
insect_gp.D = InsectSprays[InsectSprays$spray == "D",]
subset(InsectSprays, subset = (InsectSprays$spray == "D"))
insect_gp.D = InsectSprays[
    InsectSprays$spray == "D",
]
# 변수 SUBJECT를 기준으로 crop 자료를 분할
head(crop[crop$SUBJECT == unique(crop$SUBJECT)[1]], n = 2)
head(crop[crop$SUBJECT == unique(crop$SUBJECT)[2]], n = 2)
head(crop[crop$SUBJECT == unique(crop$SUBJECT)[3]], n = 2)
head(crop[crop$SUBJECT == unique(crop$SUBJECT)[4]], n = 2)

# LOCATION에 포함된 값을 오름차순으로 저장한 목록 생성
loc.list = unique(crop$LOCATION, decreasing = F)

# 생성한 목록 내 세 번째 값을 LOCATION 값으로 가지는 관찰값을 crop3로 저장
crop3 = crop[crop$LOCATION == loc.list[3],]
### split(x = <data>, f = <key_factor>)
insect_gp = split(InsectSprays, f = InsectSprays$spray)
str(insect_gp) # list로 저장됨.
insect_gp$D # indexing
crop_split = split(crop.raw, f = crop.raw$SUBJECT)
# 이렇게 하면 원래 SUBJECT 안에 있던 값들
# "RICE"    "WHEAT"   "MAIZE"   "SOYBEAN"
# 각각의 이름으로 data 프레임이 만들어짐. 
# 한 마디로 list 안에 data frame 이 4개가 있는데
# 그 각각의 이름들이 "RICE"    "WHEAT"   "MAIZE"   "SOYBEAN"
str(crop_split)
nrow(crop_split$MAIZE) ; nrow(crop_split[[1]])
nrow(crop_split$RICE) ; nrow(crop_split[[2]])
nrow(crop_split$SOYBEAN) ; nrow(crop_split[[3]])
nrow(crop_split$WHEAT) ; nrow(crop_split[[4]])

 

근데 아래와 같이 반복해서 나타내기에는 코드가 너무 길어짐.

그래서 lapply(), sapply() 사용

- X의 각 원소에 FUN(함수)을 적용하고 그 결과를 list 또는 vector로 반환하는 함수

- lapply(x = <list>, FUN = <function>) # list로 반환

- sapply( x = <list>,  FUN = <function> )  # vector로 반환 

- apply(x, margin, FUN) 

   >> x  는 matrix 또는 data.frame , 

   >> margin 은 어느 방향으로 할 건지 1은 행방향으로 2는 열방향으로 

   >> FUN은 함수 

 

예시

lapply(crop_split, nrow)
sapply(crop_split, nrow)

mat = matrix(1:111, nrow =3 )
apply(mat, 1, sum)
apply(mat, 2, sum)

 

데이터 프레임의 경우 (apply)

tmp = crop_split[[1]][, c("LOCATION", "TIME", "Flag.Codes")]
apply(tmp, 2, table)
apply(tmp, 1, is.na) # flag.codes 전체가 NA인지 의문 발생
sum(is.na(tmp$Flag.Codes)) == nrow(tmp) # flag.codes 전체가 NA임을 확인

 

주의!

함수 apply에 열 방향(MARGIN = 2)으로 is.numeric, is.character를 적용하면 실제와 모순되는 결과가 나옴.

이것은 apply가 객체를 모두 동일한 type으로 뭉그러뜨리기 때문임. 

 

is.numeric(tmp$TIME) # time은 numeric이 맞음.
apply(tmp, 2, is.numeric) # time이 numeric이 아니라고 출력됨.
apply(tmp[,3,drop=F], 2, is.numeric) # time이 numeric이라고 출력됨.

 
예시

label = sample(c("name1", "name2", "name3"),
               size = nrow(InsectSprays),
               replace = T)


sp2 = list(name1 = InsectSprays[InsectSprays$label == "name1",],
     name2 = InsectSprays[InsectSprays$label == "name2",],
     name3 = InsectSprays[InsectSprays$label == "name3",])

InsectSprays = cbind(InsectSprays, label)

sp = split(InsectSprays, InsectSprays$label)

sp2는 그냥 하나하나 정성스럽게 list에다가 넣은 것이고

sp는 split으로 label을 기준으로 나눈 것

mat1 = matrix(1:20, nr = 5, nc = 4)
mat2 = matrix(-1:-20, nr = 5, nc = 4)
mat0 = matrix(0, nr = 5, nc = 4) # 모든 항을 0으로 만들어줌. 즉, 영행렬을 만들어줌. 
mat1 + mat2 == mat0 # T, 값 하나하나를 지정해서 T를 출력해줌.
mat1 - mat1 == mat0 # T, 값 하나하나를 지정해서 T를 출력해줌.
10*mat1 ; mat1/2 # 항마다 곱해주고 나눠줌.
t(mat1) # transposed matrix(전치행렬) : 대각선을 기준으로 뒤집은 행렬

행렬 A의 덧셈의 역원: -A

항등행렬(I): 대각성분은 모두 1, 나머지 원소는 0인 행렬

 

행렬의 곱셈

AI = IA = A

AB = BA = I  # 이렇게 되면 A의 역원은 B가 됨.

- 항등원 : 이항연산을 했을 때 자기자신이 나오게 만드는 원소 

- 역원: 이항연산을 했을 때 항등원이 나오게 만드는 원소 

- 곱셉에서의 항등원 : 단위 행렬(주 대각선의 원소가 모두 1이며 나머지 원소는 모두 0인 정사각행렬)

- 곱셉에서의 역원 : A^-1

- 행렬의 곱셈을 위해서는 좌측 행렬의 열의 수와 우측 행렬의 행의 수가 같아야 함. 

mat3 = matrix(1:9, nr = 3)
mat4 = matrix(seq(1,2,length=9), nr =3)
mat3 * mat4 # 각 원소에 대응되는 것끼리 곱셈
mat3 %*% mat4 # 행렬의 곱셈
det(mat3); det(mat4)
mat5 = matrix(c(1,2,1:7), nr = 3)
det(mat5)
solve(mat5) # 역행렬

 

역행렬이 존재하는 경우의 해 구하기

# 1
# 3 + 9x = 6
# 5 + 9y = 7
(c(6,7)-c(3,5))/9

# 2
# x + 3y = -2
# 2x + 4y = 3
ex2 = matrix(1:4, nrow=2)
solve(ex2)%*%c(-2,3) # 위의 그림의 논리가 사용된 것
# 곱 방향이 양변이 같아야 함. 
# 그러니깐 우변의 오른쪽에 A^-1이 붙으면 좌변의 오른쪽에 A^-1이 붙어야 함.

행렬 (matrix)

- 동일한 자료형인 원소로 구성된 2차원의 자료 구조 

 

 

 

 

배열 (array)

- matrix의 확장된 형태로 3차원 이상의 배열을 의미

- 동일한 자료형, n 차원 이상

array(<원소가 될 vector>,dim = c(행의 수, 열의 수, 페이지 수))
# 참조
<객체명> [<row_index>, <col_index>, <page_index>]
<객체명> [<row_index>, , ]
<객체명> [, <col_index>, ]
<객체명> [, , <page_index>]
# 예시
# 첫 항이 0이고 끝 항이 10인 길이가 48이 되는 등차수열을 원소로 가지는 3X4X4 배열 arry1
arry1 = array(seq(0, 10, length = 48), dim = c(3,4,4))

arry1[3,2,3]
arry1[3,2, ]
arry1[1, , ]
arry1[ ,3, ]

 

 

 

 

 

리스트(list)

- vector와 같은 선형구조

- 각 원소별로 다양한 형태의 자료를 가질 수 있는 다중자료형

- key와 value가 한 쌍으로 저장되며, list에 있는 자료를 참조할 경우 $를 사용

 

# 리스트 자료형 생성

vec1 = c(1,30,-3)
vec2 = c("apple", "banana", "pear")
vec3 = 1:9
arry = array(1:45, dim = c(3,5,3))
mat = arry[,,1]

l = list(vec1, vec2, vec3, arry, mat)

 

# list 참조

l
l[1] ; str(l[1]) 
# 출력 형태
# List of 1
# $ : num [1:3] 1 30 -3

l[[1]] ; str(l[[1]])
# 출력 형태
#  num [1:3] 1 30 -3

names(l)

여기서 출력형태가 l[1]과 l[[1]] 이 다른 이유는 l은 리스트의 형태인데

l[1]은 리스트에서의 첫 번째 값을 통째로 가져왔다고 하는 것이고

l[[1]]은 리스트에 있는 첫 번째의 값을 껍질을 까서 가져왔다고 하는거라서 출력형태가 다른 것이다. 

 

l = list(v1 = vec1, v2 = vec2, v3 = vec3, arry = arry, mtrx = mat) 
# 리스트의 각 원소에 대한 이름 지정
names(l) 
l
l[1] ; str(l[1]) 
# List of 1
#  $ v1: num [1:3] 1 30 -3 
# $ 옆에 이름이 붙어서 나옴. 
# v1을 참조했다는 뜻 

l[[1]] ; str(l[[1]])
# num [1:3] 1 30 -3

names(l)
l$v1 ; l$arry
names(l) = c("e1", "e2", "e3", "e4", "e5"

 

 

 

 

데이터 프레임(data.frame)

- 행과 열로 구성된 2차원 표

- 열 단위로 서로 다른 자료형의 벡터를 저장할 수 있음.

- 각 열에 해당하는 벡터의 길이가 같음.

- 데이터 프레임 생성할 때 vector 여러개를 저장할 수는 있지만 matrix를 저장을 vector와 같이 하면 자료가 이상해지는 것을 확인할 수 있음.

 

# data.frame의 생성
# vector를 이용

vec1 = c(1,30,-3)
vec2 = c("apple", "banana", "pear")
vec3 = 1:9
arry = array(1:45, dim = c(3,5,3))
mat = arry[,,1]

dat1 = data.frame(num1 = vec1, 
                  chr1 = vec2, 
                  num2 = vec3[1:3] 
                  )
dat1
# data.frame의 생성
# matrix를 이용
dat2 = data.frame(mat)

matrix와 dat2의 차이점 비교

 

dat1의 첫 번째값과 두 번째 값 찾아서 각각 5번씩 출력 

dat3 = dat1[rep(1:2, each = 5),]


참조 

dat1$x1
dat2[1,]
dat2[,3]
names(dat3) = c("v1", "v2", "v3") #데이터 프레임 변수 이름 변경

자료구조 

구분 단일 자료형 다중 자료형 그외
1차원 Vector List Factor
2차원 Matrix Data Frame  
N차원 Array    

 

vector 생성

vec0 = 101
vec1 = c(1, 30, -3)
vec2 = c("banana", "apple", "pear")
vec3 = 1:9
vec4 = seq(1, 10, by = 4) # 1부터 10까지 4씩 더한 벡터
vec5 = seq(1, 100, length = 9) # 1부터 100까지 등간격으로 9개의 원소를 가짐.
vec6 = rep(1:3, times = 3) # 1:3을 3번 반복
vec7 = rep(1:3, each = 3) # 1:3의 원소를 각각 3번씩 반복

 

seq, rep 구분 

seq는 from이랑 to가 있어서 1:10 이렇게 쓰면 안되고, 1, 10 이렇게 처음이랑 끝을 구분해서 써주는 것.

rep는 x라서 다수의 숫자를 출력하고 싶을 때는 벡터로 지정을 해주거나 해야함.

seq(from = 1, to = 1, by = ((to - from)/(length.out - 1)),
    length.out = NULL, along.with = NULL, ...)
    
rep(x, ...)

rep.int(x, times)

rep_len(x, length.out)

 

vector의 참조

> 대괄호 사용 

> <객체 이름> [index number]

> 대괄호 안에 참조할 원소의 위치값을 입력

> index에는 c(), :, seq() 등으로 생성한 벡터도 가능

 

vector의 길이 확인 

> length( name_object )

 

예제

# 벡터의 3,3,3,4,4,4 번째 원소
rep(tmp3[c(3,4)], each = 3)
tmp3[rep(3:4, each =3)]

여기서 첫 번째 줄 코드를 해석하면

tmp3의 3,4 번째 숫자를 가져와서 벡터로 만들어주고, 그 다음에 각각을 3번씩 출력해준다.

두 번째 줄 코드를 해석하면

3과 4 각각을 3번 출력하고 벡터화 시킨 뒤에 tmp3의 c(3,3,3,4,4,4)의 값을 출력해준다. 

 

 

 

 

행렬(matrix)

> 수 또는 다항식 등을 직사각형 모양으로 배열한 것

> 동일한 자료형인 원소로 구성된 2차원의 자료구조

matrix(data = NA, nrow = 1, ncol = 1, byrow = FALSE,
       dimnames = NULL)
       
matrix(1:6, nrow =3, ncol =2)

 

matrix의 참조

<name_object>[<row_index>, <col_index>] # 행과 열을 함께 참조
<name_object>[<row_index>, ] # 행 참조	
<name_object>[<row_index>, <col_index>] # 열 참조

 

matrix의 차원 확인

dim(<객체명>)

 

 

예제

mat3 = matrix(seq(10, 120, by = 10), nr =2, nc = 6)
mat3[2,4]
mat3[1,]
mat3[,3]
mat3[1:2,]

 

 

 

factor 

> 범주형 자료를 표현하기 위한 구조

> 자료가 사전에 정의된 유형으로만 분류되는 경우 사용됨.

> '자료의 값'과 '사전에 정의하는 수준(level)'으로 이루어짐.

> 특수한 형태의 vector라고 볼 수 있음. 

> vector와 동일한 방법으로 참조 (대괄호 사용)

 

fac1 = factor(c("AB", "B", "O", "A", "A", "B"), level = c("A", "B", "O", "AB"))

fac2 = factor(c("B", "B", "RH-A", "B", "O", "A"), levels = c("A", "B", "O", "AB"))

fac1
fac2 # if levels factor doesn't perceive value that doesn't define in levels to NA.
# 따라서 RH-A의 값을 Na 값으로 인식함. 

fac1[1:3]
levels(fac1)
levels(fac1) = c(levels(fac1), "????") # levels에 수준을 추가

 

변수 

- 숫자나 문자열 등 하나의 항목에 이름을 붙인 것

- 1개의 변수는 하나의 데이터를 보관할 수 있음.

x1 = 5 ; x2 = 7
x1+x2
y = x2 - x1
ls() # 현재 저장된 변수 리스트 확인
rm(y) ; ls() # y만 삭제 후 변수 리스트 확인
rm(list = ls()) ; ls() # 저장된 변수 모두 삭제 후 변수 리스트 확인

 

변수의 종류 

numeric(수치형)

character(문자형)

logical(논리형)

complex(복소수형)

 

 

저장된 변수의 자료형 확인 

mode(x1) # numeric으로 출력
str(x1) # num 5로 출력
is.numeric(x1) # numeric 외에 자료형 다 가능

 

변수의 자료형 변경

as.numeric(x1) # as.character(x1)

 

# 연습
num1 =  1; char1 = 'a' ; logi1 = T

is.numeric(num1) # T
is.character(logi1) # F
is.logical(char1) # F

as.numeric(logi1) 
as.character(num1) 
as.logical(char1) # NA, character의 경우 logical로 바꿀 수 없음.
# 연습 2

as.numeric("Word")
as.numeric("1235")
as.numeric(TRUE)
as.numeric("TRUE")
as.logical(1)
as.logical(0)
as.logical(123)
as.logical("1")
as.logical(4151124)
as.numeric(F)

TRUE는 0 제외 숫자로 표현되면 1

FALSE는 0

 

 

특수 자료형

- 수학적으로 정의되지 않거나, 무한대를 나타내거나, 결측치를 나타내는 등 특수한 상황에 사용

- NA: 결측값(자리는 있음)

- NULL: 값이 존재하지 않음. (자리조차 없음.)

- NaN: 수학적인 정의가 불가능한 값 (0/0)

- Inf/ -Inf : 무한대 (3/0)

 

 

예시

x1 = c(1,2,NA, 4,5)
x2 = c(1,2,NULL, 4, 5)

is.na(x1)
length(x1)
is.na(x2)
length(x2)

결과에서 알 수 있듯이 x1은 자리가 포함되어있고, x2는 그렇지 않다. 

 

 

 

정리

temp_num = 101
temp_chr = "this is an example"
temp_logi = F
temp_cplx = 1i

is.numeric(temp_num)
is.character(temp_chr)
is.logical(temp_logi)
is.complex(temp_cplx)

as.numeric(temp_logi)

 

Review

example = read.csv("C:\\Users\\user\\OneDrive - 경북대학교\\통계학과\\1-2\\R프로그래밍 및 실험\\w5_1 covid19_psyco.csv")

# example에서 관찰값 200개를 랜덤으로 뽑고 앞 변수(열) 5개만 선택하여 example2로 저장
example2 = head(example[sample(1:nrow(example), 200), 1:5])

# example2의 occupation의 빈도표 
table(example$occupation)

# example2의 gender와 occupation의 분할표를 출력
table(example2$gender, example2$occupation)

# example2의 line_of_work에 포함된 값의 종류 확인
unique(example2$line_of_work)

 

동일한 변수 & 관찰값 추가

- 대용량의 데이터의 경우 추가된 자료만을 불러와 기존 데이터에 덧붙일 수 있음.

 예) 동일한 설문지를 조직 A,B에서 조사한 후 각각 코딩하여 자료가 두 개인 경우

 

vector에 관찰값 추가

vec = c(0,5,10)
vec = c(vec, 15)
vec[5] = 20
vec[c(6,8)] = c(25, 35) # 7번째 값은 지정해주지 않았으므로 NA값을 반환함.

 

matrix에 관찰값 추가

mat = matrix(1:10, nc = 5)
mat[3,] = rep(3,5) # 3행에 추가시켜주려고 했으나 error
rbind(mat, rep(3,5)) # 3행에 추가시켜주는 함수
mat = rbind(mat, rep(3,5))
# rbind 설명
# 벡터와 행렬, 데이터 프레임 요소들의 집합을 열로 묶어줌.

 

Practice

data(iris)
head(iris) ; tail(iris)
unique(iris$Species)

# iris에 새 관찰값 추가하기
rbind(iris, c(3.5, 3.5, 1.3, 0.3, "versicolor"))

# vector형태를 data.frame형태로 바꿔서 rbind 활용
newobs = data.frame(3.5, 3.5, 1.3, 0.3, "versicolor")
names(newobs) = name(iris)
head(rbind(newobs, iris))
str(rbind(newobs, iris))

# 두 개의 행을 가져올 때
newobs2 = data.frame(
			c(3.5, 3.7),
            c(3.5, 3.6),
            c(1.3, 1.4),
            c(0.3, 0.4),
            c("versicolor", "virginica"))
names(newobs2) = names(iris)
rbind(iris, newobs2)

 

변수 추가

예) 동일한 조사집단에 대하여 추가적인 설문 문항이 제작된 경우

 

matrix

mat = matrix(1:10, nr = 5)

cbind(mat, c(1:5)+3) 
cbind(c(1:5)+3, mat) 
cbind(mat, c(1:5)+3, c(1:5)-3) # 순서대로 저장됨.
cbind(c(1:5)+3, mat, c(1:5)-3)
# cbind 설명
# Take a sequence of vector, matrix or data-frame arguments and combine by columns.

 

data.frame

paste("id", 10) # 입력한 2개의 문자를 띄어쓰기써서 붙여주기
paste0("id", 10) # 입력한 2개의 문자를 띄어쓰기없이 붙여주기

example3 = example[sample(1:nrow(example), 10), 1:5] #여기서 example은 전에 썼던 파일 (covid)
new = paste0("id", 1:nrow(example3))

#### add variable(1) ----
cbind(example3, new)
cbind(new, example3)

#### add variable(2) ----
example3$id = new
example3[, c("id", "age", "gender","occupation", "line_of_work", "time_bp")]
example3[,c("age", "id", "gender", "occupation", "line_of_work", "time_bp")]

 

Pracitce

iris_1 = iris[iris$Petal.Length == 3.5,]
# iris_1 = subset(iris, Petal.Length == 3.5)

iris_2 = iris[iris$Petal.Length == 5,]
# iris_2 = subset(iris, Petal.Length == 5)

rbind(iris_1, iris_2)
Length = iris$Petal.Length + iris$Sepal.Length
cbind(iris, Length)

 

데이터 병합

- 데이터 합치기

>>> 기준이 없는 경우 : rbind(행 방향), cbind(열 방향) 

>>> 기준이 있는 경우(기준변수가 있는 경우) : merge

                  기준에 따라 inner join, outer join, left join, right join

 

inner / outer

left    /  right

 

 

예제

df1 = data.frame(
    ID = 1:6,
    group = c(rep("B",3), rep("A",2), "B")
)

df2 = data.frame(ID = 3:7, score =c(31,86,76,83,53))

## merge 사용 ----

# inner join
merge(df1, df2) #merge(df1, df2, by ="ID")

# outer join 
merge(df1, df2, all = TRUE)

# left join
merge(df1, df2, all.x = TRUE)

# right join    
merge(df1, df2, all.y = TRUE)

# 중복되는 변수가 존재하는 경우(값이 완전히 동일)
df3 = data.frame(ID=3:5, score=c(31, 86, 76))
merge(df2, df3, by="ID") # score.x와 score.y가 나옴.
merge(df2, df3, by="ID")[,c("ID","score.x")]

 

Practice 

# mtcars의 자료에 k-번째 관찰값이면 'car_k' 값을 가지는 변수 id를 맨 앞에 추가하여 cars로 저장
cars = cbind(id = paste0("car", nrow(mtcars)), mtcars)

# cars 자료 중에 1~10번째 관찰값을 추출하고 변수 id, mpg, disp만 cars1으로 저장
cars1 = cars[1:10, c("id","mpg","disp")]

# cars 자료 중 '1~5번째 관찰값'과 '6번째 이후 관찰값에 대하여 랜덤으로 추출한 5개의 관찰값'에 대하여 
# 변수 id, mpg, cyl만 cars2로 저장
cars2 = cars[c(1:5, sample(6:nrow(cars), size = 5)), c("id","mpg","disp")]

# 함수 merge를 활용하여 변수 id를 기준으로 cars1, cars2에 대하여 inner join/ left join/ outer join
merge(cars1, cars2, by = "id")
merge(cars1, cars2, by = "id", all.x = TRUE)
merge(cars1, cars2, by = "id", all = TRUE)

Review

# 내장 데이터 iris3 불러오기
data(iris3)

# iris3의 데이터 구조 파악하기
str(iris3)

# iris3의 세 번째 페이지의 행의 수 구하기
nrow(iris[,,3])

# iris3의 세 번째 페이지의 변수 Sepal L.의 분산 구하기
var(iris3[,"Sepal L.",3])

# 값 "A", "B", "C"를 중복 허락하여 iris3의 세 번째 페이지의 행의 수만큼 추출한 벡터 label 생성하기
label = sample(c("A", "B", "C")nrow(iri3[,,3]), replace = True)

 

외부 데이터 불러오기

read.csv(file, header = TRUE, ..)

read_excel(path, col_names = TRUE, ...)
read_xls()
read_xlsx()

# readxl 패키지에 포함된 함수들은 패키지 설치가 필요함.
install.packages("readxl")
library(readxl)

 

csv 파일로 불러오는걸 선호하기 때문에 csv파일로 불러오는 걸 공부하겠음.

excel

### install readxl ----
install.packages("readxl")
library(readxl)

### loading excel ----
read_xlsx("C:\\Users\\user\\OneDrive - 경북대학교\\통계학과\\1-2\\R프로그래밍 및 실험\\w5_1 covid19_psyco.xlsx")

read_xlsx("C:\\Users\\user\\OneDrive - 경북대학교\\통계학과\\1-2\\R프로그래밍 및 실험\\w5_1 covid19_psyco.xlsx", col_names = T)

readxl:: read_excel("C:\\Users\\user\\OneDrive - 경북대학교\\통계학과\\1-2\\R프로그래밍 및 실험\\w5_1 covid19_psyco.xlsx", sheet = 2)

readxl:: read_excel("C:\\Users\\user\\OneDrive - 경북대학교\\통계학과\\1-2\\R프로그래밍 및 실험\\w5_1 covid19_psyco.xlsx", na = "NA")

readxl:: read_excel("C:\\Users\\user\\OneDrive - 경북대학교\\통계학과\\1-2\\R프로그래밍 및 실험\\w5_1 covid19_psyco.xlsx", na = "7")

 

csv 파일로 불러오는걸 선호하기 때문에 csv파일로 불러오는 걸 공부하겠음.

 

csv

setwd("C:\\Users\\user\\OneDrive - 경북대학교\\통계학과\\1-2\\R프로그래밍 및 실험")
# 내가 어디 폴더에서 파일을 가지고 작업을 수행할지 정해줌.
# 자기 파일 클릭하고 우클릭하면 속성이 있는데 거기서 파일이 어딨는지 정보가 있으니
# 그걸 복사 붙여넣기하면 됨. 
# 근데 처음에 복사하면 \ 가 한 개만 나오는데 
# \를 \\이렇게 만들어줘야함. 

temp = read.csv("w5_1 covid19_psyco.csv", header =FALSE) 
# 파일 불러오기
# header는 column_names를 변수로 쓸건지 아닌지 FALSE는 안 쓴다는거
str(temp) 
head(temp, n = 5)
tail(temp)
temp$X ; temp$travel.work
unique(temp$age)
10 %in% temp$time_dp
5:10 %in% temp$time_dp
5:10 %in% head(temp$time_dp)

# temp에서 temp$X, temp$travel.work 열을 제거한 데이터 프레임 example 생성하기
example = temp[, -c(20,22)]
example = temp[, !(names(temp) %in% c("X", "travel.work"))]
example = subset(temp, select = -c(X, travel.work))

 

EDA

summary(example)

table(example$prefer)
table(example$age, example$prefer)

hist(example$time_bp)
hist(example$home_env)

example$certaindays_hw = as.factor(example$certaindays_hw)
str(example)

 

Practice1

# temp의 변수 age 내 오타를 수정하고 확인
temp[temp$age == "Dec-18"] == "12-18"

# na개수
sum(is.na(temp$X)) 
sum(is.na(temp$travel.work))

# na개수와 temp의 행의 수가 같은지 확인
sum(is.na(temp$X)) == nrow(temp)
sum(is.na(temp$travel.work)) == nrow(temp)

 

Practice2

names(temp) 
# 를 통해서 X와 travel.work이 column의 몇 번째인지 알아보기

example = temp[,-c(20,22)]
example = temp[,!(names(temp) %in% c("X", "travel.work")]
exmaple = subset(temp, select = -c(X, travel.work))

# subset(x, select,...)
## x : object to be subsetted
## select : expression, indicating columns to select from a dataframe
### 여기서 select 안에 있는 column의 변수들은 "" 표시 X

 

파일 내보내기

setwd("C:\\Users\\user\\OneDrive - 경북대학교\\통계학과\\1-2\\R프로그래밍 및 실험")

result = table(example$age, example$prefer) 
# age가 행 부분이 되고, prefer이 열 부분이 됨. 

write.csv(result, file = "table.csv")
# result라는 데이터 프레임을 csv로 저장  
write.csv(table(example$age, example$prefer), file = "table2.csv")
 
write.csv(example[1:3, 1:4], file = "dataframe.csv")
# example의 1부터 3부분의 행과 1부터 4의 열을 추출해서 csv 파일로 만들고 파일 이름은 dataframe.csv

 

리스트 저장하기

write.csv(list(a = example[1:10, 1:4], b = 1:10),
          file = "list1.csv")

이런 식으로 저장됨.

 

write.csv(list(a = example[1:10, 1:4], b = 1:5),
		file = "list2.csv")

 

1번째 데이터 프레임과 2번째 데이터 프레임의 F열 값이 다르다는 것을 확인할 수 있음.

이게 왜냐면 

write.csv(list(a = example[1:10, 1:4], b = 1:10),
          file = "list1.csv")
write.csv(list(a = example[1:10, 1:4], b = 1:5),
		file = "list2.csv")

10개의 행을 불러오는건 둘 다 같은데, b의 값이 1부터 10까지인거랑 b가 1부터 5까지인 것에서 차이가 난다는 걸 확인할 수 있음. 

 

다른 방법

erer::write.list(list(a = example[1:3,1:4], b = 1:10), file = "list_.csv") # a가 행으로 들어감.

 

 

.rdata

### rdata 
setwd("C:\\Users\\user\\OneDrive - 경북대학교\\통계학과\\1-2\\R프로그래밍 및 실험")
save(result, file = "rda file.rda") 
# save(result, file = "rda file.rdata")
# R의 고유한 저장형식
# 현재까지 작업한 환경을 현 작업공간(working directory)에 저장함.

save.image(file = "image.rda")
# 현재 작업 중인 공간 전체를 저장 
load("image.rda")
load("rda file.rda")
# "로드"는 외부 파일에 저장된 데이터나 객체를 R 프로그램에서 사용할 수 있도록 가져오는 과정

 

load의 사용

기존의 global Environment는 이런 상태임.

그런데

load("image.rda")

해주면

이렇게 생김.

전에 있던 파일의 저장된 데이터와 객체를 가져와줄 수 있도록 함. 

+ Recent posts