본문 바로가기

[R] apply 함수 간단 예제 (apply, lapply, sapply)

R Programming/Basic by hyem__ 2023. 11. 27.

본 게시글은 간단 예제 데이터의 연산 과정을 살펴보면서, apply 계열 함수의 작용에 대해 다룬다.

apply 함수란, 일반적인 data.frame이나 matrix (2 by 2)를 예시로 들면, 열 또는 행 방향으로 옵션으로 받는 function()을 수행하는 함수이다.

 

내부적으론 for문이 작동되나 반복 횟수만큼 함수를 호출해야 하는 for문과 달리, 함수 호출을 한 번만 하기 때문에 연산 속도가 for문을 사용하는 것보다 더 빠르다.


Apply 함수

기본 내장 apply 함수로 apply(), lapply(), sapply() 등이 있다. 이 중에서 lapply를 가장 많이 사용하는 것 같다.

apply 계열 함수는 input과 output 데이터 형식에 따라 다른 이름을 가질 뿐이며, 사용 방법은 거의 동일하다.

apply(X, MARGIN, FUN, ...)
  •  X: 연산을 적용할 데이터.
  •  MARGIN: 행(1), 열(2) 방향으로의 FUN 처리.
  •  FUN: 연산에 사용할 함수.

간단 예시

다음과 같은 matrix 데이터를 생성한다.

행과 열의 이름을 지정하여, 나중 계산 결과의 구분이 쉽도록 하였다.

m <- matrix(c(1,2,3,1,2,3), ncol=3, byrow=TRUE)
colnames(m) <- c("col1", "col2", "col3")
rownames(m) <- c("row1", "row2")
print(m)

#      col1 col2 col3
# row1    1    2    3
# row2    1    2    3

 


1. apply

먼저, apply 함수는 설정한 MARGIN의 방향에 따라, FUN 연산을 수행해 준다.

 - MARGIN = 1: 행을 기준으로 연산 처리.

apply(m, 1, mean)
# row1 row2 
#    2    2

 

 - MARGIN = 2: 열을 기준으로 연산 처리.

apply(m, 2, mean)
# col1 col2 col3 
#    1    2    3

 


2. lapply

lapply는 apply 계열이면서, list 형태로 결과를 반환한다.

apply와 달리, MARGIN 값을 받지 않기 때문에 차이점을 이해하고 사용해야 한다.

 

input 값 x가 matrix인지, data.frame인지에 따라 계산 결과에 약간의 차이가 발생한다.

먼저, x를 matrix 값으로 받았을 땐, 하나의 원소에 대한 계산 결과를 산출해 준다. (틀린 사용법)

> lapply(m, mean)
# [[1]]
# [1] 1
# 
# [[2]]
# [1] 1
# 
# [[3]]
# [1] 2
# 
# [[4]]
# [1] 2
# 
# [[5]]
# [1] 3
# 
# [[6]]
# [1] 3

 

아마 대부분은 data.frame()을 씌웠을 때의 결과를 예상할 것이다.

이때, MARGIN의 지정없이, 자동으로 열을 기준 FUN을 연산한다.

lapply(data.frame(m), mean)
# $col1
# [1] 1
#
# $col2
# [1] 2
#
# $col3
# [1] 3

 

만약, 행을 기준으로 계산하고 싶다면, 다음과 같이 코드를 작성해도 좋다.

n_row <- nrow(m)
lapply(1:n_row, function(t) mean(m[t, ]) )

# [[1]]
# [1] 2
# 
# [[2]]
# [1] 2

 


3. sapply

sapply는 apply 계열이면서, array 형태로 결과를 반환한다.

 

lapply와 마찬가지로, matrix 형태로 input을 넣으면 하나의 원소에 대한 결과를 반환한다. (틀린 사용법)

sapply(m, mean)
# [1] 1 1 2 2 3 3

 

데이터 프레임 형태로 x 값을 지정하면, 다음과 같은 결과를 얻을 수 있다.

이 때 출력된 결과는 배열형태이나, 하나의 배열에 이름이 col1, col2, col3으로 지정된 것이다.

sapply(data.frame(m), mean)
# col1 col2 col3 
#    1    2    3

 

똑같이 행을 기준으로 한 결과를 얻고 싶다면, 다음과 같이 사용할 수 있다.

sapply(1:n_row, function(t) mean(m[t,]))
# [1] 2 2

 

반응형