본문 바로가기
Data Analysis/R

[R] Apply 함수를 알아보자

by 불탄오징어 2020. 4. 21.
반응형

 

 

 

보통 apply 계열 함수라고 이야기 하는데 apply, tapply, lapply, mapply 등 apply 이름 앞에 영문자가 하나 붙는 형태로 구성이 됩니다. 보통 입력값과 출력값에 따라서 함수 종류가 달라지며 용도는 짧은 코드로 반복 명령 수행을 위해 사용합니다.

 

함수 설명
apply 주어진 데이터를 행 또는 열 기준으로 연산을 수행하는 함수
tapply 지정한 그룹(Factor) 기준으로 연산을 수행하는 함수
lapply 실행결과가 list 형태로 출력되는 함수
sapply lapply의 simple 버전

 

 

성능


for 문에 비해서 인지,가독성은 떨어질 수 있지만 apply 계열 함수를 이용하는 이유는 짧아지는 코드와 성능 때문이라고 합니다. 실제로 저도 특수한 경우를 제외하고는 apply 계열, 특히 lapply와 sapply함수를 많이 사용합니다. 간단한 테스트를 위해 아래와 같은 코드를 실행해봤습니다.

# 테스트용 데이터 셋 생성
test <- data.frame()
test <- do.call('rbind', lapply(1:1000, function(x) iris[,1:4]))  # 영원히고통받는 iris

# lapply
system.time(lapply(1:10000, function(x) sum(test)))

# for
system.time(for(i in 1:10000) {sum(test)})

 

 

물론 for문도 나쁘다는 것을 의미하는 것은 아닙니다. 활용하기에 따라서는 apply 계열의 함수가 나을 수도 있고 for문을 통해서 좀더 다양한 결과를 도출할 수 도 있습니다. 

 

 

1. Apply


tapply 함수는 데이터의 행, 열 기준으로 연산을 수행하는 함수입니다. 함수의 기본 형태는 다음과 같습니다.

 

apply(X, MARGIN, FUN)

- X : matrix, array 형태의 데이터
- MARGIN : 1은 행, 2는 열을 의미하며 이 둘 중 하나를 입력하면 행 또는 열 기준으로 FUN에 주어진 함수 실행
- FUN : 적용할 함수

 

행/열 기준의 예는 다음과 같습니다.

 

# 행기준
apply(iris[,1:4], 1, mean)

 

# 열기준
apply(iris[,1:4],2,mean)

 

 

2. tapply


tapply 함수는 주어진 Factor 기준으로 그룹 연산을 위한 함수 입니다. 함수의 형태는 다음과 같습니다.

 

tapply(X, INDEX, FUN)

 

- X : vector 형 데이터
- INDEX : 1개 이상의 factor이며 X와 length가 같아야함
- FUN : 적용할 함수

 

tapply(iris$Sepal.Length, iris$Species, mean)

 

 

3. lapply


결과를 list 형으로 반환하는 apply계열 함수로 필자가 가장 좋아하며 가장 많이 쓰는 apply 계열 함수입니다. 사실 lappy를 좋아한다기보다 list 형을 좋아하기 때문인데요. list는 특정한 데이터 제약없이 data.frame, vector 등 다양한 변수형을 하나의 변수로 묶어서 관리할 수 있습니다. 보통 function을 사용할 경우 하나의 변수형을 반환하는 경우가 많은데 list를 활용하면 한번에 여러 다른 형태의 결과를 반환할 수 있습니다. 그리고 lapply를 사용하여 data.frame으로 여러개 반환했을 경우 do.call()함수를 이용하여 한번에 하나의 data.frame으로 합칠 수 있습니다.

함수의 형태는 다음과 같습니다.

 

lapply(X, FUN)

- X : vector
- FUN : 적용할 함수

 

기본예제

lapply(1:4, function(x) sum(iris[,x]))

 

 

앞서 말한바와 같이 결과가 data.frame으로 반환되는 경우 do.call('rbind')를 사용하여 한번에 data.frame으로 합칠 수 있습니다. 먼저 아래와 같이 실행하면 총 4개의 data.frame이 list에 담겨서 반환됩니다.

 

lapply(1:4, function(x) subset(iris, iris[,x] > 2))

 

4개의 data.frame은 모두 열의 갯수도 같고 열의 이름도 같으니 아래의 코드를 실행합니다.

do.call('rbind', q)

댓글