Recent Posts
Recent Comments
Link
Today
Total
03-11 06:38
관리 메뉴

Hippo's data

R 기본문법 정리 - 1 본문

R

R 기본문법 정리 - 1

Hippo's data 2023. 9. 3. 23:55
728x90

영어는 되는데 한글 띄어쓰기 안될시

Global options -> Appearance -> zoom 을 110%나 125%로 설정

모를때 - ?모르는거 예)?mean ?by

 

변수명을 한번에 바꿀때 - ctrl + F 검색창에 바꿀변수를 치고 바꾸고 싶은 변수명을 쓴 다음 replace all

전체주석처리 = 쉬프트+방향키로 전체선택+컨트롤+C

rm(list=ls()) - 사전에 정의한 변수 날리기 (만든 알고리즘이 잘 작동하나 확인할 때)

gc() -

- 이후 다른 변수명을 넣어도 잘 작동하는지 확인

-----------------------------------------------

1

거듭제곱 : ^

2^3

[1] 8

 

몫 : %/%

5 %/% 2

[1] 2

 

나머지 : %%

5 %% 2

[1] 1

 

지수함수 : exp(x)

exp (1)

[1] 2.718282

 

로그함수 : log(x, base = exp(1))

log (2, base = 2) - (지수 , base= 밑)

[1] 1

---------------------------------------------------

2-1

파일저장 - 컨트롤+S

 

integer 정수 숫자L 예) 2L

double 실수 - R에서 쓰는 대부분의 숫자 예 ) 2.3 (점 붙여서 사용)

3이라고만 치면 실수로 나오기 때문 (정수이지만) - 정수, 실수 굳이 구분 X

 

complex 복소수 - 거의 안다룸 (2+1i)

 

typeof() 해당 데이터 종류 알기

 

is.integer(), is.double(), is.numeric(), is.complex() 함수로 숫자의 - numeric(실수)

종류가 해당 함수의 종류가 맞는지 확인할 수 있음.

as.integer(), as.double(), as.numeric(), as.complex() 함수로 다른

종류의 숫자를 함수에 해당하는 숫자 종류로 바꿀 수 있음.

 

R에서 문자(character) ”(큰따옴표) 또는 ’(작은따옴표)로 표시함.

예를 들어 ”1”은 숫자 1이 아닌 문자 1을 나타냄.

as.character() 함수를 통해 문자로 변환할 수 있음.

만약 문자에 큰따옴표를 넣고 싶다면 작은따옴표로 묶어주고 작은따옴표를 넣고 싶다면 큰따옴표로 묶어주면 됨.

x<-"'1'" [1] "'1'"

문자처리된 숫자는 숫자로 변환 가능

as.integer(“1”) 1

일반적인 문자는 숫자로 변환시 NA값 나옴

NA not available 값이 존재하지 않음이라고 값이 정의되있음

원래 값이 있어야하지만 지금은 없는 상태(결측)

 

0/0 NAN

not a number 수학적으로 정의되지 않는 

 

NULL 공간이 아얘 빔, 텅빈 공간

 

x = NA

object.size(x) 56 bytes

y <- NULL

object.size(y) 0 bytes

 

논리자료형 - T / F 로 쓰기도함

 

크거나 같다 표시

>= (O)

=> (X) - 순서 바뀌면 안됨

2==3 두 값이 같냐 ( = 한개는 할당자)

!= 같지 않냐 1 != 1 1이랑 1은 같지않냐? F

not T, F 값 바꿔서 출력 (반대로 출력)

 

<문자 대소비교 가능>

인코딩 순서따라 트루값나옴

“가” < “나” T

“A” > “B” F

날짜 다룰 때 많이 사용

날짜 대부분 문자로 처리 “20210101” - 만약 숫자로 처리되어 다른 숫자가 더해진다면 애매해짐

20210101 + 40 = 2월로 넘어가지 않고 1월 41일로 됨

"20210101" < "20210312" T 3월이 1월보다 미래인가?

문자자리수 주의 - 년도4자리, 월2자리, 일2자리 8자리로 정해져야 정확히 대소비교 가능

"20210101" < "202111" 같은 1월1일이지만 T로 나옴

not ! 반대로 출력

and & 둘다만족시 T

or | 둘중하나 만족시 T

 

TRUE는 숫자 1과 같고 FALSE는 숫자 0과 같음. ( 웬만하면 안씀 )

-------------------------------------------------------------0

2-2

여러개의 값을 변수에 할당

벡터 = 최소 단위의 값들의 묶음

한 벡터에 한 데이터종류로만 구성가능

벡터생성 c()

변환가능한, 포괄가능한, 상위 종류로 변환

문자>숫자>논리값

문자> only 문자로만 가능

숫자> 숫자, 문자 가능

논리값> 숫자, 문자, 논리값 가능 – T, F

 

예) a <- c(1, “a”, “b”) “1”, “a”, “b”

c <- c(F, 1, 2) 0, 1, 2

 

벡터는 평평(flat)한 구조를 갖기 때문에 중첩할 수 없음.

벡터끼리 쉽게 이어붙일 수 있음

a<-c(1, 2, 3)

b<-c(a,4,5) 1, 2, 3, 4, 5

 

벡터에는 각 원소에 대응되는 이름을 지정

height <-c("김" =166, "이" =142, "최"=176)

height <-c( 166, 142, 176)

names(height)<- c("김", "이", "박")

 

heights = c(160,140,155) #heights 벡터 생성

heights[c(2,1,2)] #heights의 2, 1, 2번째 원소 추출 [1] 140 160 140

 

[ ] 대괄호 속 번호 = 옆에 있는 원소가 몇 번째 원소인지

[1] 1 3 5 7 9 11 13 15 17

[10] 19 21 23 25 27 29 31 33 35 - 19는 10번째 원소

[19] 37 39 41 43 45 47 49 51 53

[28] 55 57 59 61 63 65 67 69 71

 

펙터(factor) 범주형 변수(10대, 20대 등) 를 나타내기 위해 사용됨

사용자에게는 문자로 보이지만 사실 숫자

메모리를 더 적게 사용

x<- c(“10대”, “20대”, “30대”)

 

y<- c(1, 2, 3)

1:“10대”, 2:“20대”, 3:“30대”

범주에 대응되는 숫자를 지정하여 숫자로 저장

저장 방식의 차이로 메모리 적게 사용

y<- factor(x, levels = c("10대", "20대", "30대"))

[1] 10대 20대 10대

Levels: 10대 20대 30대 - “30대”라는 레벨 추가해줌

 

table() - 벡터에 같은 값이 몇 번 나왔는지 카운트 해줌

 

행렬(Matrix) - 벡터를 2차원 구조로 나타낸 형태 (행, 열)

한가지의 데이터 종류만 가질 수 있음

 

matrix(data, nrow, ncol, byrow=T/F )

 

기본적으로 행부터 채움 (F)- 세로방향으로

T – 가로방향으로

nrow나 ncol 중 하나만 입력했을 경우 나머지 하나는 벡터의 길이를 고려해서 자동으로 결정됨.

행렬에서도 rownames()와 colnames() 함수로 행과 열 각각 이름을 부여할 수 있음

colnames(x) <- c("A", "d")

--------------------------------------------------------------------0

2-3

 

배열(Array) - n차원 구조를 가진 데이터 종류로 벡터, 행렬을 포함하는 일반적인 형태임

모든 원소가 한가지 데이터 종류로만 이루어질 수 있음.

array(data, dim) - dim - 차원

 

dim에 c(3, 2, 2)를 입력하면 3x2x2 배열이 생성됨. 쉽게 말하면 3행 2열인 행렬이 2개 (3x2x2 차원의 구조) 생성됨

 

데이터 프레임(Data Frame) - data.frame(첫번째열, 두 번째열, ...) 열을 하나씩 추가함

  다른 종류의 데이터를 가질 수 있음/ 같은 열안에는 같은 데이터형태 가져야함

df<-data.frame(a=c(1,2,3), b=c(2,3,4), row.names =c("c","d","e"), stringsAsFactors = T)

열을 하나씩 쓰는 형식

 

a b 칼럼에 이름을 a,b 로 할당

c 1 2 로우에 이름을 c,d,e로 할당

d 2 3

e 3 4

 

stringsAsFactors - factor 형식으로 저장함

 

결측치 입력하고 싶으면 NA 쓰기

칼럼 계속 추가 가능

 

행렬과 마찬가지로 colnames(), rownames() 함수를 이용하여 행과 열의 이름을 변환시킬 수 있음.

colnames(df) <- c(“A”,“B”)

A B - 열 이름이 바뀜

c 1 2

d 2 3

e 3 4

 

str() - structure 데이터 프레임의 각 열이 어떠한 데이터 종류로 저장되어있는지 알 수 있음.

str(df)

'data.frame': 3 obs. of 2 variables:

$ a: num 1 2 3

$ b: num 2 3 4

 

리스트(list) - 거의 모든(?) 자료형을 저장할 수 있음

각각 다른 자료형이 저장될 수 있음

 

list(a= vector,b = matrix, array, dataframe) - 여러 자료형 묶어줄 수 있음

각 자료형에 a,b 등 이름도 붙일 수 있음

 

가 = 벡터 [1:3] - 1부터 3까지 있다.

나 = 행렬(매트릭스) [ , ] 콤마 한번당 차원한개씩 나뉨

-------------------------------------------------0

3-1

인덱싱(Indexing)은 객체(벡터, 행렬 등)의 특정 원소(데이터)에 접근하는 것

특정 원소를 뽑는 행위

원소 혹은 데이터의 이름을 이용 / 위치를 이용하는 방법있음

슬라이싱(Slicing)은 인덱싱과 같은 개념이지만 일련의 원소들에 접근하는 것

일련의, 주루룩 된 원소를 뽑는 것 , 구분필요 X

 

벡터 인덱싱 – 대괄호 사용

<위치이용>

양의 정수 이용 – 해당위치만 뽑음

x <- c(5,6,7,8,9,10)

x[1] 5

x[3] 7

 

x[c(1,3)] 5 7 - 여러개 뽑을 때는 벡터형태로 만들어서 입력

 

음의 정수 이용 – 해당위치 제외하고 뽑음

x <- c(5,6,7,8,9,10)

x[-1] 6 7 8 9 10

 

x[c(-1 , -2)] 7 8 9 10

x[-c(1, 2)] 7 8 9 10

 

논리형 벡터 인덱싱 - 특정 조건만족하는 것만 뽑기 / T값 뽑기

x <- c(5,6,7,8,9,10)

x[c(T,F,T,F,T,F)] 5 7 9 - T값만 뽑음/ 일반 벡터값과 논리형 벡터랑 대응해야 하므로 길이가 같아야함

 

x[x>6] 7 8 9 10

x>6 FALSE FALSE TRUE TRUE TRUE TRUE [ ]안의 값이 논리형 벡터가 나오기 때문

 

원소에 이름이 있다면 이름을 통해 벡터 인덱싱을 할 수 있음.

<이름이용>

x1 <- c(a=1, b=2, c=3, d=4)

 

x1["a"] a 1 - [ ]안에는 캐릭터 형태로 쓰기

 

x1[c("a", "c", "d")] a c d 1 3 4 - 여러개 뽑을 땐 벡터형태로

 

x1[-"a"] - 이름에서는 –로 특정 문자 빼고 뽑기 안됨 - %in%, which 함수 이용

 

x1[!(names(x1) %in% c("b", "c"))] - a d 1 4 - b,c 빼고 뽑기

x1[-which(names(x1) %in% c("b","c"))] a d 1 4 - which는 숫자로 나오므로 –사용가능

 

 

%in% - 어떤 벡터 특정 원소가 다른 벡터에 포함되어 있는지를 TRUE 혹은 FALSE로 반환해주는 연산자

x %in% y – x 원소가 y에 포함되어 있는지 여부 나타냄

x <- c(1,2,3,4,5)

y<- c(1,3,5)

x %in% y TRUE FALSE TRUE FALSE TRUE

 

match - 특정 원소가 몇번째에 있는지 반환

match(1 ,c(2,1,4)) - 2 - 1원소가 두번째에 있음

 

which() - 입력되는 논리형 벡터에서 TRUE의 원소 위치를 반환해주는 함수 – 숫자형으로 반환

which(x %in% y) 1 3 5 - T 원소가 1, 3, 5번째에 있음

 

행렬 인덱싱

대괄호에서 콤마(,)로 행과 열을 구분하여 인덱싱 / 행(콤마앞), 열(콤마뒤)

양의 정수 이용 – 벡터 인덱싱과 동일 – 해당하는 몇행, 몇열의 원소 값을 추출

음의 정수 이용 – 특정 원소제외한 나머지 뽑는게 아니고 해당 전체 행, 열을 제외한 값 반환

<정수로 인덱싱>

a <- matrix(c(1,2,3,4,5,6), 3,2)

[,1] [,2]

[1,] 1 4

[2,] 2 5

[3,] 3 6

 

a[1,1] 1 - 1행 1열 원소값 추출

a[c(1,2),1] 1 2 - 1행,2행 1열 원소값 추출

 

a[c(-1,-2),1] 3 - 1,2행 제외 1열 추출

 

* 전체 행 혹은 전체 열을 반환받고 싶은 경우 대괄호 내의 해당 행 또는 열을 공백으로 두면 됨.

a[1,] 1 4 - 1행의 모든열

a[,2] 4 5 6 – 2열의 모든 행

 

<논리형 인덱싱>

a[c(F,T,F), c(T,F)] 2

 

a[,1]>1 FALSE TRUE TRUE - 1열에서 1보다 큰 값

a[a[,1] >1,] - 1열에서 1보다 큰값인 원소의 행 원소 추출

[,1] [,2]

[1,] 2 5

[2,] 3 6

 

a>2 - 전체 행렬에서 2보다 큰값 표시

[,1] [,2]

[1,] FALSE TRUE

[2,] FALSE TRUE

[3,] TRUE TRUE

 

a[a>2] 3 4 5 6 - 전체 행렬에서 2보다 큰 원소 뽑음

 

*행렬에서 인덱싱을 했을 때, n × 1 혹은 1 × n의 행렬이 반환될 경우 벡터로 반환

*행렬의 구조를 유지하고 싶은 경우에는 drop = FALSE라는 인자를 통해 인덱싱 후 행렬의 구조를 유지할 수 있음 (행렬간 연산시 주의)

 

a[,1] 1 2 3 - 벡터로 출력 (자동으로 벡터출력 기능)

a[,1,drop = F] - 행렬 유지 / 원래는 한 열만 추출시 벡터형식으로 추출되지만 매틔릭스 구조 유지하고 싶을때 이용

[,1]

[1,] 1

[2,] 2

[3,] 3

<이름 인덱싱>

colnames

rownames

v1 V2

a 1 3

b 2 4

 

a[,"v1"] 1 2 - v1 이름으로 된 열 추출

 

a[c("a"),] - a 이름으로 된 행 추출

v1 V2

1 3

 

a["a","V2"] 3 - a이름행, V2이름 열 추출

 

a[c("b",2),"V1"] - 에러생김 – c()벡터안에는 같은 종류의 타입을 가져야함

 

*이름, 정수형 혼용가능

a[1,"V2"] 3 - 1번째행, V2이름 열 추출

 

데이터 프레임 인덱싱 - 기본적으로 행렬인덱싱과 유사

name weight

1 Park 100

2 Kim 56

3 Jung 44

4 Lee 68

 

dat[,2] - [1] 100 56 44 68 열 인덱싱 – 벡터형식으로 나옴

dat[2,] - Kim 56 행 인덱싱 – 데이터프레임 형식으로 나옴(여러 데이터 종류 섞여있기 때문)

 

X[”변수명”] : 변수명에 해당하는 열을 데이터 프레임으로 반환

 

dat["name"] dat[,"name",drop=F]와 같은 결과

name

1 Park

2 Kim

3 Jung

4 Lee

 

X$변수명(열이름) : 변수명에 해당하는 *******모든 행의 값을 반환***** - [ , $] 인덱싱시 안에쓰면 X (인덱싱시에는 특정 열을 지칭해야 하기 때문)

$쓸시 있는 열이름이 다 뜸

dat$name " Park " "Kim " " Jung " "Lee " - 해당 열의 행값을 반환

dat$weight 100 56 44 68

 

리스트 인덱싱

벡터 인덱싱과 유사, 데이터프레임의 $ 인덱싱 지원

 

[ ] 해당 인덱스의 리스트가 반환

[[ ]] 해당 인덱스의 리스트 안의 데이터를 반환 (데이터 종류 유지)

$a

[1] 1 2 3

 

$b

c d

1 2 3

2 3 4

3 4 5

 

x[1] $a - 리스트 값으로 출력

[1] 1 2 3

 

x[[1]] [1] 1 2 3 - 1번째 리스트안의 데이터만 출력 x$a와 같은값 출력

 

[[ ]]- 대괄호 2개를 이용한 다중 인덱싱, 음의 정수를 통한 인덱싱 불가능

(여러개 데이터 종류를 혼합하여 가져올 수 없기 때문)

[ ] - 대활호 1개를 이용하여 리스트 종류 유지한 채 인덱싱은 가능

x[[c(1,2)]] - 각 리스트 종류 유지한채 1,2번째 리스트를 뽑으려 했으나 실패

 

x[c(1,2)] - 리스트 구조 유지한 채로 여러개 뽑아올 순 있음

$a

[1] 1 2 3

 

$b

c d

1 2 3

2 3 4

3 4 5

 

x[-2] $a - 2번째 리스트 제외한 출력

[1] 1 2 3

 

원소의 수정 -인덱싱 후 해당 원소에 덮어씌우기

<벡터>

x<- c(1,2,3,5)

x[4] <- 4 - 4번째 원소를 4로바꾸기

x [1] 1 2 3 4

y[y>4] <- 0

y<- c(1,2,3,4,5,6) [1] 1 2 3 4 0 0 - 4초과값 다 0으로

<행렬>

[,1] [,2]

[1,] 1 4

[2,] 2 7

[3,] 3 8

 

x[c(2,3), 2] <- c(5,6)

[,1] [,2]

[1,] 1 4

[2,] 2 5

[3,] 3 6

 

<데이터 프레임>

name gender

1 Park M

2 Kim F

3 Lee M

 

dat[dat$name == "Park","gender"] <-"F" - $이용하여 name이 Park인 행을 선택

 

dat$name<- c("choi", "park", "kim") - 이름 한번에 변경

 

name gender

1 choi M

2 park F

3 kim M

 

* 새로운 열을 추가하고 싶을 때

1) dat$age <- c(24,11,53) - $에 없는 변수 쓰기

2) dat[ ,"age"] <- c(24,11,53)

 

name gender age

1 choi M 24

2 park F 11

3 kim M 53

 

<리스트 원소 수정>

$a

[1] 1 2 3

 

$b

[,1] [,2]

[1,] 1 3

[2,] 2 4

 

1) x[[1]] <- c(5,6) - 대괄호 두 개는 벡터로 나오므로

2) x$a

3) x[["a"]]

4) x[1] <- list(c(5,6)) - 대괄호 한 개는 리스트로 나오므로

5) x[“a”]

$a

[1] 5 6

 

$b

[,1] [,2]

[1,] 1 3

[2,] 2 4

 

*통째로 바꾸지 않고 하나의 원소값만 바꿀 때 - 2중 인덱싱

1) [[ ]] [ ] 중복사용

2) $$ 연속사용

x[[2]][2,1] <- 10 - 2번째 리스트의 2행1열값을 10으로 바꾸기

 

$b

[,1] [,2]

[1,] 1 3

[2,] 10 4

 

x$b$[,1] <- c(0,0) - $ 연속으로 인덱싱 가능

----------------------------------------------------------------------0

3-1

연산

 

벡터연산 – 요소별 연산

x<-c(1,2,3,4)

y<-c(2,4,6,8)

x+y [1] 3 6 9 12 - 원소별로 계산됨

길이 다른 경우 - 재사용 규칙(recycle rule) 적용

x<-c(1,2,3,4,5)

y<-c(2,4,6)

x+y [1] 3 6 9 6 9 - y(2,4,6,2,4)로 계산 짧은 쪽의 원소를 재사용하여 더해줌

 

벡터와 스칼라(길이 1인 벡터)의 연산시 broadcasting이 적용

x<-c(1,2,3,4,5)

y<-3

x+y [1] 4 5 6 7 8 - y(3,3,3,3) 으로 계산되는것과 같은 값

 

행렬연산

1. 행렬과 스칼라(길이 1인 벡터) 연산

[,1] [,2]

[1,] 1 3

[2,] 2 4

 

X+1 [,1] [,2] - X + matrix(c(1,1,1,1),2) 와 같은 값

[1,] 2 4

[2,] 3 5

 

 

2. 행렬과 벡터 연산

y<-c(10,11)

X+y [,1] [,2] - X + matrix(c(y,y), ncol=2) 와 같은 값

[1,] 11 13 [,1] [,2]

[2,] 13 15 [1,] 10 10

[2,] 11 11

 

 

3. 행렬과 행렬 연산 – 구조 맞지 않으면(행과 열의 개수가 다르면) 연산되지 않음 (브로드캐스팅 불가능)

Y<- matrix(c(10,11), ncol=1)

[,1]

[1,] 10

[2,] 11

 

X= [,1] [,2]

[1,] 1 3

[2,] 2 4

 

X+Y 불가능

 

*는 원소별 곱을 수행

행렬곱은 %*%로 계산

 

데이터 프레임 연산

%*% 작동하지 않음 - as.matrix() 함수이용하여 행렬곱 연산

dat1 <- data . frame ( a = c(1, 2) , b = c(3, 4))

dat2 <- data . frame (c = c(5, 6) , d = c(7, 8))

 

as.matrix(dat1) %*% as.matrix(dat2)

---------------------------------------------------------0

3-3

함수(function)

 

sum() 함수

x<- c(1,2,3)

y<-c(4,5,6)

sum(x,y) 21 - sum안에 넣은 모든 원소를 다 더함

 

na.rm 이용 – NA값 제거후 계산

z<-c(1,2,NA)

sum(z[!is.na(z)]) = sum(z,na.rm=T) - 결측치 제외한후 더해줌

 

mean() 함수

trim 절사평균구함 = 최고,최저점 일정수치만큼 제외후 나머지 값들로 평균을 내는 것

 

x<- c(1,9,10,11,100)

mean(x) 26.2

mean(x,trim = 0.3) 10 - (원소개수)5 X 0.3 = 1.5에서 소수점 내림 = 1만큼 최저,최고값 원소제외후 평균

 

na.rm 이용

z<-c(1,2,NA)

mean(z,na.rm = T) 1.5 - (1+2)/2 = 1.5

*결측값 NA를 0으로 보고 계산할 때

z[is.na(z)] <- 0

mean(z) 1 - (1+2+0)/3 = 1

 

max(), min() 함수 – 최대,최소

-character(문자)도 가능

d<- c("20190301", "20190302", "20190303") - 날짜를 문자형태로 저장

max(d) "20190303" - 가장 미래날짜

min(d) "20190301" - 가장 과거날짜

 

which.max(), which.min() 함수 – 최대, 최소값이 원소의 몇 번째에 위치하나

x<-c(2,4,6,8,10)

which.max(x) 5

which.min(x) 1

 

x<-c(1,1,2,2,3,3)

which.max(x) 5 - 겹치는 원소중 가장 작은(빠른) 위치 값을 반환

 

sort() 함수 - 내림차순, 오름차순 정렬

decreasing = TRUE 내림차순 정렬 (안할 경우 기본은 오름차순 정렬)

x<-c(2,1,6,4,8,3)

sort(x) 1 2 3 4 6 8

sort(x,decreasing = T) 8 6 4 3 2 1

 

order() 함수 – 원래 원소의 위치값으로 오름,내림차순 정렬

기본은 오름차순으로 정렬

x<-c(2,1,6,4,8,3)

order(x) 2 1 6 4 3 5 x벡터묶음에서 2번째 원소값(1)이 제일작으니 처음위치로와야함

1번째 원소값(2)이 2번째로 작으니 2번째위치

6번째 원소값(3)이 3번째로 작으니 3번째 위치

4번째 원소값(4)

3번째 원소값(6)

5번째 원소값(8)

order(x, decreasing = T) 5 3 4 6 1 2 - 내림차순

 

x[order(x)] 1 2 3 4 6 8 - 완전히 오름차순으로 인덱싱 - 데이터프레임 정리시 이용

예)

sepal_length sepal_width species

1 5.1 3.5 virginica

2 4.9 3.0 setosa

3 4.7 2.9 versicolor

4 4.6 3.4 versicolor

5 4.4 3.8 virginica

6 5.5 4.0 virginica

 

sort(dat$sepal_length) 4.4 4.6 4.7 4.9 5.1 5.5 - 입력된 벡터값들만 오름차순(행값 전체가 움직이지 않음)

dat[order(dat$sepal_length),]

dat[ 5 4 3 2 1 6(오름차순으로 정렬된 위치표시- 원래 데이터에서 6번째 행이 제일 크므로 마지막에 위치 ...), ]

sepal_length sepal_width species

5 4.4 3.8 virginica

4 4.6 3.4 versicolor

3 4.7 2.9 versicolor

2 4.9 3.0 setosa

1 5.1 3.5 virginica

6 5.5 4.0 virginica

 

length() 함수 – 벡터, 리스트 길이 반환(원소 개수)

x<-c(1,1,2,2,3,3)

length(x) 6

a<- list(a=matrix(c(1,2,3,4),2), b=c(1,2,3,4))

length(a) 2

 

nrow(), ncol() 함수 – (매트릭스, 데이터프레임에서) 행, 열개수

> dat

sepal_length sepal_width species

1 5.1 3.5 virginica

2 4.9 3.0 setosa

3 4.7 2.9 versicolor

4 4.6 3.4 versicolor

5 4.4 3.8 virginica

6 5.5 4.0 virginica

nrow(dat) 6 - 6행

ncol(dat) 3 - 3열

 

dim() 함수 – (매트릭스, 데이터프레임에서) 행, 열 개수 한번에 반환

dim(dat) 6 3 - 6행 3열

 

head(), tail() 함수 – 위/아래에서 몇 번째까지 출력

> dat

name age

1 Park 20

2 Kim 23

3 Lee 30

 

head(dat,2) = dat[1:2,]

name age

1 Park 20

2 Kim 23

 

tail(dat,2) = dat[2:3,] = dat[(nrow(dat)-1):nrow(dat),]

name age

2 Kim 23

3 Lee 30

 

--------------------------------------------------------------------------0

4

조건문

if문 – condition(조건)의 값이 TRUE일 경우 중괄호 코드 실행, FALSE일 경우 실행하지 않음 / 조건에 단일값

if (condition) {실행할 내용}

한줄에 하나의 실행 내용만 써야함 만약 한줄에 여러개 쓰고 싶다면 ; 사용

x<- 1 - 보통 한줄에 하나만 씀

if (x>0) {

x<-x+1

x<-2+x

}

 

x<- 1 - 한줄에 여러개 쓸 경우 ; 사용

if (x>0) {x<-x+1; x<-2+x}

 

* 여러원소가 입력되면 첫 번째 원소를 이용하여 조건을 체크함

x<- 1

if (c(T,F,F)) {x<-x+1} - 첫 번째 원소가 TRUE 이므로 실행

x 2

*any, all을 통해 조건을 단일값으로 만들어줌 ( x<-1:3에서 if문 조건이 x>1인 경우 F,T,T 값인 다중값으로 나옴)

any() - 적어도 하나의 원소가 조건을 만족하면 TRUE값 반환

x<- 1:3

any(x>1) TRUE - c(1,2,3) 중에 1보다 큰 값이 2개 있으므로 TRUE

 

all() - 모든 원소가 조건을 만족하면 TRUE값 반환

all(x>1) FALSE - c(1,2,3) 중에 1보다 큰값이 2개뿐이므로 FALSE

 

&& || - 첫 번째 원소로 판단

x<-1:3

x>1 && x<3 FALSE (x>1 & x<3)[1]와 같은 값 - c(1,2,3)중 첫 번째 원소 1이 조건을 만족하지 못하므로 F

x>1 || x<3 TRUE (x>1 | x<3)[1]와 같은 값 - 첫 번째 원소 1이 3보다 작다에 만족하므로 T

 

else – FALSE일 경우 실행

x<-1:3 - x==4인 값이 하나도 없으므로 else구문 실행

if (any(x==4)){

x<-x+1

} else {

x<-x-1

} [1] 0 1 2

 

else if – 여러 조건을 계속 추가하고 싶은 경우

if ( ) { }

else if ( ) { }

else { }

 

*if문에서 FALSE 값은 전혀 실행되지 않으므로 실수할 수 있음 – FALSE 위치라도 조건을 다 확인하고 변수도 할당되어 있는지 확인 (예 - Z는 변수에 없는데 Z변수를 실행시키라고 하면안됨)

 

 

ifelse() 함수 - 원소별로 TRUE와 FALSE를 판별

ifelse(test,yes,no) test= T, F 섞여있는 논리형 벡터, yes= T인 경우 할당할 값, no= F인 경우 할당할 값

 

예 ) 수업에서 4명의 학생의 중간고사 성적이 70, 55, 88, 30점이라 하자.

70점 이상인 학생은 A, 70점 미만인 학생은 B라고 할당한다면

 

score<- c(70, 55, 88, 30)

achv <- ifelse(score >= 70, "A", "B")

achv [1] "A" "B" "A" "B"

-------------

achv <- c()

if(score[1] >=70){achv[1]<-"A"} - 조건에 단일값만 들어가야 하기 때문

else {achv[1]<-"B"}

 

if(score[2] >=70){achv[2]<-"A"}

else {achv[2]<-"B"}

 

if(score[3] >=70){achv[3]<-"A"}

else {achv[3]<-"B"}

 

if(score[4] >=70){achv[4]<-"A"}

else {achv[4]<-"B"}

---------------

긴 구문과 같은 효과

 

* ifelse() 함수도 조건 여러개 추가시 ifelse 중첩해서 사용

score <- c(70, 55, 88, 30)

achv <- ifelse ( score >= 70, "A", ifelse ( score >= 50, "B", "C"))

[1] "A" "B" "A" "C"

switch() 함수 - 입력하는 값이 조건만족시 다른 값으로 대체 – 입력하는 값이 character(문자)만 가능

name <- " Beomjin " - 1개 값만 가능 (길이1인 벡터)

switch ( name ,

Beomjin = " good ",

Sangjun = " Nice ",

Sion = " stupid ")

[1] " good “

-----------------------------------------------------0

5-1

반복문

for (i in data) {반복할 내용}

data안의 원소를 하나씩 i에 할당하며 data의 원소 개수만큼 반복, i는 임의의 변수 아무거나 지정가능

x<- c("H", "E", "L", "L", "O")

for (i in x) {

print(i)

}

[1] "H"

[1] "E"

[1] "L"

[1] "L"

[1] "O"

 

x<- 1:1e+6 - 1부터 10의 6승까지의 원소

y<-0 - y에 1부터 10의 6승까지 다 더해라 = sum(x)와 같은 값

for (i in x){

y<-y+i

} [1] 500000500000

 

system.time( ) - 괄호안의 실행에 얼마나 시간이 걸리는가

system.time( - elapsed 0.03 0.03초 시간이 걸림

for (i in x){

y<-y+i

}

)

 

*for문의 data자리에 행렬, 데이터 프레임, 리스트 사용 가능  보통은 벡터를 사용

x<- matrix(1:6, ncol=2, byrow = T)

[,1] [,2]

[1,] 1 2

[2,] 3 4

[3,] 5 6

for (i in x){ - data 자리에 행렬 쓰일시 원소개수만큼 반복

print(i)

}

[1] 1 - 행렬에서 아래방향으로 반환- 1열의 1,2,3행 2열의 1,2,3행 순서대로

[1] 3

[1] 5

[1] 2

[1] 4

[1] 6

 

dat<- data.frame(x1=1:5,x2=5:1)

x1 x2

1 1 5

2 2 4

3 3 3

4 4 2

5 5 1

 

for (i in dat){ - data 자리에 데이터프레임 쓰일시 열(변수) 개수만큼 반복

print(i)

}

[1] 1 2 3 4 5 - 변수 통째로 i에 할당

[1] 5 4 3 2 1

 

a<- list(a= 1:5,

b=matrix(1:6,ncol=2),

c=data.frame(x1=1:5,x2=5:1))

 

for (i in a){ - data 자리에 리스트 쓰일시 자료 개수만큼 반복

print(i)

}

[1] 1 2 3 4 5 - 처음엔 벡터 그대로 할당, 두 번째는 매트릭스 그대로 할당, 세 번째는 데이터프레임 그대로 할당

[,1] [,2]

[1,] 1 4

[2,] 2 5

[3,] 3 6

x1 x2

1 1 5

2 2 4

3 3 3

4 4 2

5 5 1

 

*for문을 중첩 - 가장 안쪽의 for문이 먼저 다 돌아간 후 그다음 for문의 반복이 진행됨

 

for (i in 1:3){ - i가 1일 때 j1,2 돌고 i가 2일 때 j1,2 돌고 i가 3일 때 j1,2 돌고

for (j in 1:2){

print(i*j)

}

}

[1] 1 i*j = 1*1

[1] 2 1*2

[1] 2 2*1

[1] 4 2*2

[1] 3 3*1

[1] 6 3*2

for문 예제1 : 구구단 테이블 만들기

number<-1:9 - 1:3, 1:5, 1:13 등 구구단의 길이가 변할때도 성립되도록

mat<- matrix(0,nrow=length(number),ncol=length(number))

- number의 크기(구구단 단수)가 변할 때도 성립되도록

 

for (j in number){

for (i in number){

mat[i,j]<-j*i

}

}

mat [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]

[1,] 1 2 3 4 5 6 7 8 9

[2,] 2 4 6 8 10 12 14 16 18

[3,] 3 6 9 12 15 18 21 24 27

[4,] 4 8 12 16 20 24 28 32 36

[5,] 5 10 15 20 25 30 35 40 45

[6,] 6 12 18 24 30 36 42 48 54

[7,] 7 14 21 28 35 42 49 56 63

[8,] 8 16 24 32 40 48 56 64 72

[9,] 9 18 27 36 45 54 63 72 81

for 문 예제2 : 분식집 - grid search 알고리즘 = 최적화 문제(어떤 경우에 내 이익이 최대/최소가 되는가)

시험가능성

범진이는 친구 상준이와 함께 떡볶이와 순대를 먹으러 갔다. 떡볶이 1인분과 순대 1인분을 시키니 떡이 24조각 순대가 10조각이 나왔다.

순대를 좋아하는 상준이가 앞에서 째려보고 있기 때문에 범진이가 먹을 수 있는 순대는 최대 6조각, 순대와 떡볶이를 합쳐 15조각 이하만 먹을 수 있다.

또한 항상 떡볶이를 먹은 개수가 순대를 먹은 개수의 두배보다 많아야 한다.

떡볶이는 한조각당 포만감을 4만큼 주고 순대는 5만큼 준다고 할 때, 범진이가 포만감을 최대로 느끼기 위해서는 순대와 떡볶이를 몇조각씩 먹어야 하는지 구하시오.

ddeok <- 0:24

soondae <- 0:10

grid<- expand.grid(ddeok = ddeok, soondae = soondae)

 

* expand.gird - 넣은 변수의 가능한 모든 조합 계산

 

ind<- (grid$soondae <=6)& -grid 변수에 조건(순대가 6이하) 만족하는 것만 T 반환

(grid$soondae + grid$ddeok <=15)&

(grid$ddeok >2*grid$soondae)

 

 

grid[ind, ] - ind 조건에 만족하는(TRUE) 원소들을 grid 데이터 프레임의 행에서 뽑음

nrow(grid[ind,]) [1] 45 - 총 45개의 변수들이 조건을 만족함 (조건을 만족하는 행 개수)

 

candidate<- grid[ind, ] - candidate 변수에 담음

 

x<- c() - 포만감을 계산할 빈 벡터 / 포만감을 계산해서 차곡차곡 쌓을 예정

 

temp<- candidate[1,] - 조건을 만족하는 candidate 변수의 1행을 temp 변수에 담음

x[1] <- 4*temp$ddeok + 5*temp$soondae - 포만감을 계산하여 x 빈 벡터에 쌓음

 

temp<- candidate[2,]

x[2] <- 4*temp$ddeok + 5*temp$soondae - 위의 반복을 for문으로 작성

 

for (i in 1:nrow(candidate)){

temp<- candidate[i,]

x[i] <- 4*temp$ddeok + 5*temp$soondae

}

 

x - 순대, 떡볶이 조합의 포만감 계산값이 들어있음

[1] 0 4 8 12 16 20 24 28 32 36 40 44

[13] 48 52 56 60 13 17 21 25 29 33 37 41

[25] 45 49 53 57 61 26 30 34 38 42 46 50

[37] 54 58 62 39 43 47 51 55 59 63 52 56

[49] 60 64 65

 

which.max(x) [1] 45 - x에서 최댓값 변수가 45번째 위치

candidate[which.max(x),]

ddeok soondae

112 11 4

-----------------------------------------------0

5-2

while문 - 반복문

while (condition) {반복할 내용}

 

for문 - 주어진 데이터의 원소를 순차적으로 뽑거나 원소 개수만큼만 반복

while문 - 조건(condition)이 TRUE인 동안 계속해서 반복을 수행하게 됨 (FALSE가 되면 종료됨) / 반복문 실행하다가 멈추고 싶을 때 ESC버튼

 

for문 구구단 예제 – while문으로 변환

number<- 1:9

mat<- matrix(0,nrow=length(number), ncol=length(number))

 

i <- j <- 1 - i, j 에 1을 넣어라 - for문에서 i, j 의 역할 / while문은 변수를 데이터에서 뽑아서 할당하는 기능이 없기 때문에 따로 지정이 필요

첫번째 방법

while(j<=length(number)){

while(i <=length(number)){

mat[i,j]<- i*j

i <- i+1

}

i<-1 - 중간에 while문이 돌고 나면 i는 10이 되서 끝나므로 초기화하는 작업이 필요

j<-j+1

}

두번째 방법 – condition(조건)값에 i j 변수 넣기

i <- j <- 0 - i, j의 초기값을 0으로 할당

 

while((j<-j+1) <=9){ - 초기값 0에 1을 더한 1부터 시작하여 반복

while((i <- i+1) <=9 ){

mat[i,j]<- i*j

}

i<-0 - 다시 0으로 초기화

}

세번째 방법 - 멈추는 조건을 if문으로 활용

cond1<- cond2<-TRUE

i <- j <- 1

 

while(cond1) {

while(cond2){

mat[i,j]<- i*j

i<- i+1

if(i>=10){ -i 값이 10이 넘으면 cond2에 FALSE를 할당하여 반복문 멈춤

cond2 <- FALSE

}

}

i<-1 - 다시 i 값 초기화

cond2<- TRUE - 다시 cond2 값 초기화

j<-j+1

if(j>=10){

cond1<- FALSE

}

}

 

* break – 반복 멈춤 / 들어있는 위치의 반복문만 멈춤

네번째 방법 - while문에 TRUE를 할당한 후 조건달성시 break를 이용하여 반복문 멈춤

 

repeat문 - while문의 조건에 항상 TRUE를 입력한 것과 같음 while(TRUE){ } = repeat{ } / break를 이용하여 멈춤

while (TRUE) { - while(TRUE) { } 대신 repeat{ }를 대신 사용 가능

while (TRUE) {

mat[i,j]<- i*j

i<- i+1

if(i>length(number)){

break

}

}

i<-1

j<-j+1

if(j>length(number)){

break

}

}

 

숫자 야구 게임

숫자 야구 게임은 출제자가 0-9까지 서로 다른 3자리 숫자를 임의로 정한 뒤, 응답자가 3자리 숫자를 불러가며 출제자가 정한 숫자를 맞힘.

숫자는 맞지만 위치가 틀렸을 때는 볼, 숫자와 위치가 전부 맞으면 스트라이크, 숫자와 위치가 전부 틀리면 아웃.

예) 출제자가 123이라는 숫자를 정하고 응답자가 102라고 답을 했을 때는 1스트라이크 1볼임.

ask <- c(9,3,1)

correct <- c(3,5,2)

strike <-0

ball<- 0

 

correct의 1번째 원소랑 ask의 1,2,3번째 원소랑 비교 / 2랑 123 / 3이랑 123 각각 비교

j <- 1 - correct에서 1번째 원소 뽑음 - i,j 는 몇번째 자리인지 표시

i < - 1 - ask에서 1번째 원소 뽑음

i <- 2

i <- 3 j2/i123/j3/i123

= for문이 2개 필요함을 인식

 

correct[ j ] - correct에서 j 번째 원소의 값

ask[ i ] - ask에서 i 번째 원소의 값

 

(correct[j]==ask[i]) - 값이 같은경우

(j==i) - 자리가 같은 경우

 

 

if((correct[j]==ask[i]) & (j==i)){

strike <- strike - 계속 더해가는 코드

}

if((correct[j]==ask[i]) & (j != i)){

ball <- ball +1

}

 

출력메세지

 

paste("a",3, sep="") - 서로 붙일때 / sep="" 붙는 값 사이 띄어쓰기를 조정 / 변수를 넣어서 변수값과 붙일 수 있음

[1] "a3"

 

answer<- paste("strike : ",strike,", ball : ",ball, sep="")

[1] "strike : 0, ball : 0"

 

if((strike + ball)==0){

answer<- "out"

} else {

answer<- paste("strike : ",strike,", ball : ",ball, sep="")

}

 

for문 대신 %in%로 작성

 

ask<- c(7,3,6)

correct <- c(3,5,2)

 

sum(ask == correct) - ask와 correct의 자릿수끼리 비교/ 같은 자리의 숫자가 같으면 T 다르면 F /sum을 통해 T=1, F=0 이므로 T의 개수를 파악

 

(correct %in% ask) - correct 변수들이 ask에 들어있나? 있으면 T 없으면 F

 

ball<- sum(correct %in% ask) - strike

 

if((strike + ball)==0){

answer<- "out"

} else {

answer<- paste("strike : ",strike,", ball : ",ball, sep="")

}

while문으로 맞출때까지 물어보는 알고리즘

 

계단 오르기 시험가능성

하교길에는 계단이 있는데 철수와 영희는 20번 가위바위보를 해서 이긴 사람이 한칸씩 오르는 게임을 함.

비길 경우에는 아무도 계단을 오르지 않음.

철수가 가위, 바위, 보를 낼 확률은 각각 0.1, 0.7, 0.2이며 영희가 가위, 바위 보를 낼 확률은 각각 0.2, 0.3, 0.5

이러한 게임을 100일동안 했을 때 철수가 오른 계단의 평균과 영희가 오른 계단의 평균은?

 

sample(x = ,size = ,replace = ,prob = )

x - 랜덤하게 추출할 데이터 입력

size – 데이터에서 몇개 뽑나 / 만약 가위바위보에서 하나빼기일게임으로 2개내면 2

replace – replacement 복원or비복원 추출 / 복원추출 = T, 비복원추출 = F / 한개뽑을땐 안써도됨

prob – probability / 각 데이터가 뽑힐 확률

-------------------

x<-c("가위", "바위", "보")

chul <- sample(x =x ,size = 1 ,prob = c(0.1,0.7,0.2))

chul

 

young<- sample(x =x ,size = 1 ,prob = c(0.2,0.3,0.5))

young

 

누가 이겼는지 나타내는 값 필요 – if문 등 다양한 방법 가능 / 매트릭스 이용

mat<- matrix(0, nrow = 3, ncol = 3)

rownames(mat)<-x

colnames(mat)<-x

가위 바위 보

가위 0 0 0

바위 0 0 0

보 0 0 0

 

철수 승 –1, 비김 0, 영희 승 1

mat[1,]<- c(0,-1,1)

mat[2,]<- c(1,0,-1)

mat[3,]<- c(1,-1,0)

가위 바위 보 - 행 변수는 영희가 낸 값 / 열 변수는 철수가 낸 값

가위 0 -1 1

바위 1 0 -1

보 -1 1 0

 

mat[young,chul]

 

days <- 100 - 100일 반복

result_mat <- matrix(nrow = days, ncol = 3) -행은 100일 승무패 기록 , 열은 철수승,영희승,비긴횟수 기록

 

winner_vec<-c() - 빈벡터를 만들어서 반복시마다 이긴횟수를 저장

for (i in 1:20){

chul <- sample(x =x ,size = 1 ,prob = c(0.1,0.7,0.2))

young<- sample(x =x ,size = 1 ,prob = c(0.2,0.3,0.5))

winner<-mat[young,chul]

winner2<-switch(as.character(winner),

"-1" = "철수",

"0" = "무승부",

"1" = "영희")

winner_vec[i]<-winner2

}

 

table(winner_vec) - 각 값이 몇번 나왔는지 카운트 / 만약 한 데이터값이 0일 경우 길이가 2나 1로 되기 때문에 X

무승부 영희 철수

11 7 2

result_mat[1,]<- table(winner_vec)

table(factor(winner_vec, levels = c("무승부", "영희", "철수"))) - 펙터에 레벨을 지정해서 길이를 3으로 맞춰줌 – 안나오는 경우에도 0으로 카운트함

 

최종식

for (j in 1:days){

winner_vec<-c()

for (i in 1:20){

chul <- sample(x =x ,size = 1 ,prob = c(0.1,0.7,0.2))

young<- sample(x =x ,size = 1 ,prob = c(0.2,0.3,0.5))

winner<-mat[young,chul]

winner2<-switch(as.character(winner), - 가위바위보 결과 어떻게 됐나

"-1" = "철수",

"0" = "무승부",

"1" = "영희")

winner_vec[i]<-winner2

} - 하루 가위바위보의 결과

result_mat[j,]<- table(factor(winner_vec,

levels = c("무승부", "영희", "철수")))

}

colMeans(result_mat) - 열별로 평균을 내줌

[1] 6.49 8.55 4.96 - 무승부, 영희승, 철수승 횟수 평균

---------------------------------------------------------0

5-3

apply계열 함수 - for문과 유사한 기능 (다 for문으로 작성가능, 더 간결하게 표현)

- (apply, lapply, sapply) - 자주 사용 / tapply-그룹별연산 가끔사용 / (vapply, mapply) - 거의사용X 등

 

apply() 함수

배열, 행렬 또는 데이터 프레임 – 2차원 데이터구조에서 적용할 함수(max, maen, min, sum 등) 행,열별로 적용해서 결과를 벡터, 행렬, 리스트로 반환

 

apply(X, MARGIN, FUN, ...)

X : 배열, 행렬 또는 데이터 프레임 – 행렬구조를 가진 데이터 입력

MARGIN : 함수를 적용하는 방향. 1은 행방향, 2는 열방향

FUN : 적용할 함수 - mean, min, mat, sum 등

... : FUN에 입력된 함수의 추가적인 인자. 예) mean(x,trim=) - mean 함수의 trim인자 쓰면 절사평균 적용

*데이터 프레임에서 열별로 다른 데이터종류가 입력되어 있는 경우 – 행렬로 변환되므로(같은 종류의 데이터형식)주의- 만약 문자, 숫자 섞여있다면 숫자도 문자형식으로 변환

 

x<-matrix(1:6, ncol=2)

apply(x, 1,mean ) [1] 2.5 3.5 4.5 - 행별로 평균 구함 = rowMeans(x)와 같은 효과

apply(x, 2, var) [1] 1 1 - 열별로 분산구함

apply(x,1,sd) [1] 2.12132 2.12132 2.12132 - 행별로 표준편차 구함(standard deviation)

 

res<- c()

for (i in 1:nrow(x)){ - for문보다 간결하게 표현 가능

res[i]<- var(x[i,])

} [1] 4.5 4.5 4.5

x[1,1]<-NA

colMeans(x) - 평균계산시 NA값 있을 시 계산값도 NA 반환

[,1] [,2]

[1,] NA 4

[2,] 2 5

[3,] 3 6

apply(x, 1, mean, na.rm=T) - na.rm 이라는 추가적인 인자사용하여 결측치(NA) 없애고 계산

[1] 4.0 3.5 4.5

*행, 열별로 계산시 벡터형태로 넘어가서 적용하고자 하는 함수(sum, mean 등)에서 계산 – 벡터형태로 계산되지 않는 함수(rowMeans 등) 입력시 계산X

 

lapply() 함수

-벡터, 메트릭스, 리스트(원소별로 적용) / 데이터프레임(열별로 적용 – for문과 유사) 결과는 only 리스트로 반환

margin(행, 열 방향)의 인자는 필요없음- 기본적으로 벡터, 리스트는 원소별 / 데이터프레임은 열별로 함수적용

 

sapply() 함수 - lapply() 함수와 같은 기능 / 결과 벡터(원소 하나씩 있을때), 배열(길이2이상일때)로 반환 (lapply는 결과를 리스트로)

 

unlist( ) - 모두 벡터형태로 반환

 

x<- list(a=c(1,2,3), b=c(2,3,4), c=c(3,4,5))

$a

[1] 1 2 3

$b

[1] 2 3 4

$c

[1] 3 4 5

lapply(x, mean) - 결과(평균)를 리스트형식으로 반환

$a

[1] 2

$b

[1] 3

$c

[1] 4

sapply(x, mean) - 결과를 벡터로 반환 - unlist(lapply(x, mean))로 리스트 없앤값과 같음

a b c

2 3 4

 

y<- list(a=matrix(1:4,2), b=matrix(1:6,2))

lapply(y, rowMeans) - 결과 리스트형태로 반환

$a

[1] 2 3

 

$b

[1] 3 4

sapply(y, rowMeans) - 결과 매트릭스 형태로 반환

a b

[1,] 2 3

[2,] 3 4

 

x<-1:3

lapply(x,"^",2) - 각 원소를 n제곱하는 함수 "^" - 각 원소의 왼쪽 값을 2제곱 / "+"는 각원소에 오른쪽만큼 더함(문자형식- “”으로 써줌)

[[1]]

[1] 1

 

[[2]]

[1] 4

 

[[3]]

[1] 9

 

x<- list(a=c(1,2,6), b=c(2,3,4), c=c(3,4,5))

lapply(x, "[",3) - "[" 각 벡터에서 3번째 값을 인덱싱(추출)

$a

[1] 6

 

$b

[1] 4

 

$c

[1] 5

 

vapply() 함수 - sapply와 같은 기능 / fun.values - 반환받는 결과값의 구조 입력

vapply(x, fun, fun.values,...) - sapply 쓰면 되지 굳이 쓰지 않음

 

x<- list(a=c(1,2,3), b=c(2,3,4), c=c(3,4,5))

vapply(x,"^",c(first=0, second=0, third=0),2) - 벡터에 이름이 붙은 형태로 나옴

a b c

first 1 4 9

second 4 9 16 - A<- sapply(x, "^",2) 와 같은값 / 직접 행이름을 따로 입력가능

third 9 16 25 - rownames(A)<-c("first", "second", "third")

tapply() 함수 – 그룹별로 함수 적용 (패키지가 이미 잘 되어있음)

tapply(x,index,fun,...) - x: 행렬로 넣을시 복잡작동 보통 벡터로 넣음/ index: 그룹으로 묶을 기준 (팩터형이 아니여도 팩터형으로 바꿔줌) - 사용하는 함수는 벡터 계산시 쓰는 함수 사용 (mean O, colMeans rowMeans X)

dat<- data.frame(math = c(45, 35, 65, 36),

eng = c(24,26,74,54),

name = c("ha", "jeong", "ga", "beom"),

test = c("mid", "final", "mid", "final"))

tapply(dat$math, dat$test, mean) - test 변수를 mid와 final 그룹으로 구분해서 math 변수의 평균을 구함

final mid

35.5 55.0

 

by() 함수 – 데이터프레임에서 그룹별로 함수적용

by(data, INDICES, FUN, ..., ) - indices – index의 복수형

by(dat[,1:2],dat$test,colMeans) - test 별로 math와 eng의 평균 / 행렬로 값이 반환되므로 행렬에서 평균 계산하는 함수적용( mean X , colMeans rowMeans O)

dat$test: final

math eng

35.5 40.0

-------------------------

dat$test: mid

math eng

55 49

 

res<-by(dat[,1:2],dat$test,colMeans)

str(res) - 결과값 구조 확인시 리스트 형태이므로

 

res$final - final에 대한 math eng 평균값을 띄어서 확인가능

math eng

35.5 40.0

 

mapply() 함수 – 데이터 입력X / 여러 함수 입력받아 함수값 반환

mapply(FUN, ...)

 

mapply(mean, iris[1:4]) - 다 같은 값 iris(붓꽃표현한 데이터프레임 내장됨)의 열의 평균 구함

 

sapply(iris[1:4], mean)

 

mean(x= iris[,1])

mean(x= iris[,2])

mean(x= iris[,3])

mean(x= iris[,4])

 

Reduce() 함수 - 벡터(리스트)의 요소를 연속적으로 결합하며 주어진 함수를 적용

Reduce(f, x, right = ) - f: 각 요소에 적용할 함수 / x: 벡터, 리스트 / right = T 일 경우 뒤에서부터계산

x<-1:10 [1] 1 2 3 4 5 6 7 8 9 10

Reduce("+",x) [1] 55

1+2 - 나온 값들을 순차적으로 계산

3+3

6+4

 

y<- list(a = matrix(1:6 , 2),

b = matrix(7:12, 2),

c = matrix(13:18, 2))

Reduce("+", y, right = T ) - 매트릭스의 원소별로 다 더함 / 처음에는 c와 b 매트릭스 더하고 그 결과값과 a 매트릭스더함

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

[1,] 21 27 33

[2,] 24 30 36

------------------------------------------------------0

6-1

사용자 정의 함수 – 원하는 기능의 함수가 없을 때

1. 코드의 반복을 피할 수 있음

2. 가독성을 높인다.

3. 디버깅(Debugging-에러처리)에 용이

4. 메모리 사용에 효율적일 수 있음

사용자 정의 함수 예시

어느 올림픽 종목에서 최고점수와 최저점수를 제외한 나머지 점수의 평균으로 점수를 채점한다고 함.

총 6명의 심사위원이 점수를 매긴다고 하고, 3명의 선수들에 대한 점수가 주어졌을 때,

3명의 선수에 대한 채점 점수를 구하여라.

score_2<- matrix(c(50, 45, 60, 88, 64, 47,

45, 55, 63, 78, 53, 30,

42, 44, 64, 70, 33, 40),

nrow = 3, , byrow = T)

rownames(score)<-c("A","B","C")

colnames(score)<-c("J1","J2","J3","J4","J5","J6")

 

A<- score["A",]

B<- score["B",]

C<- score["C",]

 

Means(A[-c(which.min(A), which.max(A))])

Means(B[-c(which.min(B), which.max(B))])

Means(C[-c(which.min(C), which.max(C))])

----------------------------------------

my_mean (A) - 위의 값을 my_mean 사용자 정의함수로 쉽게 표현

my_mean (B)

my_mean (C)

 

구조

함수 이름(Function Name)

인자(Arguments) - 생략가능

함수 본문(Function Body) - 인자(Arguments)를 받아서 구성

반환 값(Return Value) - 생략가능

 

function _ name <- function ( argument , ...) {

<function body >

return ( return value )

}

 

예시의 my mean 함수 정의하기 - return 반환값이 없을 때는 마지막에 출력되는 값이 자동적으로 반환값이 됨

my_mean <- function (x , ...) {

mean ( x [ -c( which . min( x ) , which .max ( x ))])

}

 

my_mean <- function (x , ...) { - 하지만 반환값 명시해주는게 best / A 값이 x에 할당되어 계산

val <- mean ( x [ -c( which .min( x ) , which .max( x ))])

return ( val )

}

사용 : my_mean(A)

 

가변 길이 인자 ... -알 수 없는 길이의 인자나 내부 다른 함수의 인자로 넘겨줄 때 사용

(추가적으로 인자입력하여 사용할때)

my_mean2<- function(x, ...){

val<- mean(x[-c(which.max(x),which.min(x))], ...)

return(val)

}

R<- c(NA, 2,3,4) -결측치가 들어있는 경우 계산값도 NA로 나오기 때문에 na.rm 인자 사용필요

my_mean2(R) [1] NA

my_mean2(R, na.rm=T ) [1] 3 - ...(가변길이인자)에 na.rm인자가 적용됨 / 새로 만든 사용자정의함수에 다른 인자를 넣어도 작동

 

f<-function(...){

vv<-mean(c(...))

return(vv)

}

f(1,3,5) [1] 3 - f 사용자정의 함수에 넣은 값들의 평균을 구해줌 (가변길이인자로 몇개를 넣든 다 작동)

 

임의의 숫자 n이 입력되었을 때, 구구단 n단까지 테이블을 반환해주는 함수 만들기

gugudan<- function(n){

mat<- matrix(0,nrow= n, ncol = n)

for(i in 1:n) {

for ( j in 1:n){

mat[i,j]<- i*j

}

}

return(mat)

}

gugudan(5)

[,1] [,2] [,3] [,4] [,5]

[1,] 1 2 3 4 5

[2,] 2 4 6 8 10

[3,] 3 6 9 12 15

[4,] 4 8 12 16 20

[5,] 5 10 15 20 25

------------------------------

지역변수와 전역변수

 

스코프(Scope) - 코드에 기술한 변수가 어디에서 사용 가능한지를 정하는 규칙

R은 정적 스코프(Static Scope)를 사용, 함수 내에 정의된 변수는 함수 내부에서만 접근이 가능

 

지역변수(Local Variable) -함수 내에서만 사용가능한 변수(사용자정의함수의 function body 부분에서 할당한 변수)

전역변수(Global Variable) - 콘솔에서 할당, (R이 종료되기 전까지 어디에서나 사용 가능)

*지역변수와 전역변수가 같은 이름을 갖는다면 지역변수의 사용이 우선순위가 더 높음 (지역변수에서 찾은후 없으면 전역변수를 찾고 없으면 에러)

 

<< −” 할당자 - 함수 내에서 지역변수 대신 전역변수로 값을 할당

f<- function(x){

z<<-x*2

return(z)}

f(3) [1] 6

z [1] 6 – z<-일경우 지역변수이기 때문에 콘솔창에서 z입력시 에러나야하지만 <<-로 전역변수로 할당하여 값 표시

 

재귀함수(recursive function) - 정의하는 함수에서 자기 자신을 다시 호출하여 작업을 수행

- 함수 내에서 자기 자신을 계속 호출하므로 멈추는 조건을 주지 않으면 무한루프 / 반복문으로 대체해서 표현가능

test <- function(n){

if (n==0){

print("The end")

} else{

print(n)

test(n-1) - test함수 정의하면서 function body 안에 자기자신을 사용

}

}

test(3) - 함수 값을 가지고 있다가(print()값들 ) 함수가 끝날 때 한번에 실행

[1] 3

[1] 2

[1] 1

[1] "The end"

 

*사용자 정의 함수 안에서 return을 만나면 그 순간 즉시 반환 ( 만족하는 if문 안의 return값 존재시 안의 return값 반환)

 

<재귀함수 이용 예제>

피보나치 수

F_0 = 0, F_1 = 1

F_n = F_n−1 + F_n−2, n = 2, 3, 4, . . .

fibonacci = function(n){

if (n==0){

res <-0

return(res)

} else if (n==1){

res=1

return(res)

} else {

res<- fibonacci(n-1) + fibonacci(n-2)

return(res)

}

}

fibonacci(10) [1] 55

* 피보나치 구할 때 재귀함수 사용않는 방법

---------------------------------------0

재귀함수 순서

f1<- function(n){

if (n==1){

return(print(n))

} else {

print(n)

f1(n - 1)

}

} f(3) - 321 반환

f1(3) - print후에 재귀함수존재하므로 각값에서 프린터된 후 다음 재귀함수 실행

print(3)

f1(2)

print(2)

f1(1)

print(1)

---------

f2<- function(n){

if (n==1){

return(print(n))

} else {

f2(n - 1)

return(print(n))

}

} f(3) - 123 반환

f2(3) - 재귀함수실행후 프린터값이 있으므로 전 재귀함수가 모두 실행된후 프린터값 반환

f2(2)

f2(1)

print(1)

print(2)

print(3)

 

하노이탑 hard ???

hanoi<- function(n, from, to, aux){

if(n==1){

print(paste(from, "->", to))

} else {

hanoi(n-1,from=from,to=aux,aux=to)

print(paste(from, "->", to))

hanoi(n-1,from=aux,to=to,aux=from)

}

}

hanoi(1,1,3,2) - 숫자는 링을 거는 막대기의 위치

hanoi(2,1,3,2)

hanoi(3,1,3,2)

hanoi(4,1,3,2)

 
사진 삭제

사진 설명을 입력하세요.

목표: 모든 링을 from에서 to로 옮기는 것

 

실행순서

hanoi(3,1,3,2)

n=3 ; from=1 ; to=3 ; aux=2 로 초기에 지정되어 있음

hanoi(2,1,2,3) - 재귀함수가 끝나야 다음 프린트가 실행

( n=3 ; from=1 ; to=2 ; aux=3 ) 검-빨-파 종속순서 입력됨

hanoi(1,1,3,2)

-print(paste(1,"->",3))

-print(paste(1,"->",2)) - from=1 ; to=2 들어가 있는 상태이므로

hanoi(1,3,2,1)

-print(paste(3,"->",2))

-print(paste(1,"->",3))

--------------------

hanoi(2,2,3,1) - n=2 ; from=2 ; to=3 ; aux=1 들어가 있는 상태

hanoi(1,2,1,3)

-print(paste(2,"->",1))

-print(paste(2,"->",3))

hanoi(1,1,3,2)

-print(paste(1,"->",3))

 

*제일아래링을 from에서 to로 옮기는 거 제외하고 위의 나머지 링들을 옮기는 것은 전단계(n-1)와 같음(어디로 향하고 무엇이 보조막대기 인지만 바뀜)

n=3 기준으로 생각해서 알고리즘 짜면 쉬움

 

-------------------------------

6-2

객체(Object)와 클래스(Class)

R – 객체지향프로그래밍 (Object-oriented programming, OOP) cf)파이썬

객체- 속성과 매서드로 구성 / 클래스- 객체를 만들어 내기 위한 청사진(틀)

객체– 각 데이터(정수/실수/문자 등)에 대해서만 작동하는 “전용”함수(method) 정의하고 데이터가 생성될 때 데이터와 전용함수를 묶음 ex) sum함수- 문자형더해주는sum / 숫자형(정수,실수,복소수)더해주는sum 구분

클래스- 데이터와 그 전용함수 (method)를 정의해 놓은 

 

class() - 데이터의 클래스 이름 확인 (typeof()- 각각의 데이터 값을 확인)

 

x<-c(1,2,3)

typeof(x) [1] "double" (실수)

class(x) [1] "numeric"

 

y<-matrix(1:4,2)

typeof(y) [1] "integer"

class(y) [1] "matrix" "array"

 

methods() 함수 - 메서드(method)확인

methods(class="numeric") - 클래스가 numeric인 데이터에서만 작동하는 전용함수들

[1] all.equal as.data.frame

[3] as.Date as.POSIXct

[5] as.POSIXlt as.raster

[7] coerce Ops

 

*help창 볼 때 유용함

?summary.factor – 함수뒤에 클래스입력시 해당 클래스에서 이용 가능한 인자, 설명 나옴(help창에 없을 경우 이용)

?summary - summary함수도 각기 다른 클래스에서 작동하는 여러 method들이 있음

summary(object, ...)

 

(디폴트- 원래 정의되있음/ 나온 클래스 이외의 클래스가 들어올 경우 이용)

## Default S3 method: - 입력된 데이터가 무슨 class인지에 따라 다른 인자 이용

summary(object, ..., digits, quantile.type = 7)

## S3 method for class 'data.frame'

summary(object, maxsum = 7,

digits = max(3, getOption("digits")-3), ...)

 

## S3 method for class 'factor'

summary(object, maxsum = 100, ...)

 

## S3 method for class 'matrix'

summary(object, ...)

--------------------------

K-NN 알고리즘 (K-nearest neighbor)

-예측 대상의 속성(특성, 변수)과 유사한 데이터를 사전 데이터에서 찾아 사전 데이터의 값으로 예측 대상을 예측하는 전략.

-분류(classification- 범주형 변수)와 회귀(regression- 연속형 변수) 문제 적용

두 대상 변수간의 유사도를 측정

유사도 - 유클리디안 거리(Euclidean distance) 사용 - 두 점사이의 거리 (거리가 작을 수록 유사도 커짐)

(유사도와 거리 반비례관계)

 

 

x<- matrix(c(10,9,

1,4,

9,1,

5,10,

3,10,

3,6), ncol=2, byrow=T)

colnames(x)<-c("당도","아삭함")

rownames(x)<-c("사과","베이컨","바나나","당근","샐러리","아몬드")

x_new <- c(6,4) #토마토 당도, 아삭함

 

y<- c("과일","단백질","과일","채소","채소","단백질")

 

x[1,]-x_new

 

eucd<-c()

for (i in 1:nrow(x)){

eucd[i]<- sqrt(sum((x[i,]-x_new)^2))

}

y[which.min(eucd)] # 값이 젤 작은것 = 유사도가 제일 큼

 

#####################################

x_temp<-x-matrix(x_new, nrow(x),ncol(x),byrow = T)

 

eucd<- sqrt(rowSums(x_temp^2))

y[which.min(eucd)]

############################## 사용자정의함수 만들기

# 토마토 이외 여러개 자료들도 예측

#1-nn

 

 

knn <- function(x,y,X_new){

y_pred <-c()

eucd<-c()

for (i in 1:nrow(X_new)){

X_temp<-x-matrix(X_new[i,], nrow(x), ncol(x),byrow = T)

eucd<- sqrt(rowSums(X_temp^2))

y_pred[i]<- y[which.min(eucd)]

}

return(y_pred)

}

 
728x90

'R' 카테고리의 다른 글

R 기본문법 정리 - 2  (0) 2023.09.04