|

R apply 계열 함수 이해하기

R 언어 기초를 다루면서 무한 반복 작업용으로 for() 문을 배우고 나면, 코드가 3~4줄로 지저분하게 길어지고 빅데이터가 들어왔을 때 처리 속도가 미친 듯이 느려지는 치명적 한계에 부딪히게 됩니다. 전 세계 R 데이터 통계 분석가 및 시스템 개발자들이 구시대적 for Loop 굴레 대신 무조건 고차원 함수로 넘어가서 입이 닳도록 쓰라고 강제하는 메모리 최적의 마법 기능이 바로 “apply 매핑 가문”의 함수들입니다.

이 함수들은 데이터 프레임이나 복잡한 행렬 구조의 모든 데이터 구석구석에 여러분이 지정한 특정 연산을 “동시에, 한 방의 광역기로 촥-” 뿌려줍니다. 가장 헷갈리지만 핵심인 apply, lapply, sapply 3형제의 핵심 작동 원리와 포맷 반환 차이를 명쾌하게 정리합니다.

1. 행렬 매트릭스의 심판자: apply()

가장 근간이 되는 apply() 오리지널 함수는 차원이 존재하는 2차원(2D Array) 데이터, 즉 행렬(Matrix) 구조나 엑셀 표 같은 데이터 프레임에 특정한 함수(예: sum 연산자나 평균 등)를 한 방에 들이부을 때 사용합니다. 사용할 때 파라미터에서 가장 중요한 컨트롤 키보드는 “어느 축 슬라이스 방향으로 연산을 밀어버릴 것인가”를 뜻하는 인자인 MARGIN을 정해주는 것입니다.

  • MARGIN = 1 : 횡단 방향! 즉 가로행(Row) 단위로 썰어가며 함수를 누적 계산해!
  • MARGIN = 2 : 종단 방향! 즉 세로열(Column) 단위로 위에서 아래로 꽂아 내리면서 함수를 계산해!
# 1에서 9까지의 숫자가 차곡차곡 들어있는 3x3 엑셀 같은 행렬 강제 생성
my_matrix <- matrix(1:9, nrow = 3)

# 1. MARGIN 1: "가로(행) 방향" 덧셈 축 합산! (1번행 합계, 2번행 합계...)
apply(my_matrix, MARGIN = 1, sum)
> [1] 12 15 18
# 2. MARGIN 2: "세로(열) 방향" 데이터 수직 누적 합산! (A열 합계, B열 합계...)
apply(my_matrix, MARGIN = 2, sum)
> [1]  6 15 24

2. 리스트 방들에 마법 가루 일괄 살포하기: lapply()

List-apply의 직관적 약자인 lapply() 함수는 아주 성질이 유연하고 넓습니다. 먹어치우는 타임 대상 데이터가 복잡한 여러 겹 리스트이든, 데이터 프레임이든 상관없이 구동되지만 무조건 최종 결과물을 팩킹된 리스트(List) 형태 구조를 고수하여 방 별로 쪼개 반환해 냅니다.

이론상 거대한 “데이터 프레임” 구조도 사실은 세로 기둥(벡터 모음)들을 줄줄이 묶어놓은 구조체 리스트의 일종이기 때문에 lapply()의 매우 훌륭하고 맛깔나는 먹잇감이 됩니다.

# 숫자가 3개씩 들어있는 A방, B방이 묶인 리스트 서랍장 창조
my_list <- list(a = c(1, 2, 3), b = c(10, 20, 30))

# 서랍장 뼈대 리스트 속의 모든 룸 방면에 "평균(mean)" 연산 함수를 무차별 단체 살포 폭격!
lapply(my_list, mean)
> $a
> [1] 2
> 
> $b
> [1] 20

출력 결과물 위단에 $ 표시가 고스란히 달린 길다란 세로 형태로 방이 분리되어 튀어나온 구조를 깊게 주목하세요. lapply()는 입에서 오직 껍질을 유지한 리스트만을 뿜어내는 절대 변하지 않는 원칙적 특징을 가졌기 때문입니다.

3. 스마트하게 단일 벡터로 이쁘게 압축 정리해서 보여줄게!: sapply()

콘솔 화면에 수시로 리스트 형태로 기형적으로 줄줄이 기차처럼 나오는 것이 보기에도 심히 역겹고 다시 벡터 연산에 재활용하기 부담스러웠던 선배 개발자들은, “제발 가장 단순화(Simplify)시켜서 결과를 깔끔히 보여주자”는 취지 의미로 Simplify-apply의 약자인 업그레이드형 sapply()를 파생해 만들어냅니다.

작동 사용법이나 구동 원리는 엔진 깊숙한 곳에서 위 lapply와 토씨 하나 틀리지 않고 똑같이 돌아가지만, 최종 결과물을 보고서 출력용으로 일목요연하고 깔끔한 “배열 1차원 벡터(Vector)”나 “행렬”로 껍질을 예쁘게 까서 자동으로 유추 압축해 돌려준다는 치명적이고 매력적인 특징 장점이 있습니다.

# 똑같은 서랍장 리스트 객체에, 이번엔 sapply의 지능형 빔을 발사!
sapply(my_list, mean)
>  a  b 
>  2 20

💡 초보자 패닉 코딩 고민 요약 해결법!

– 엑셀 시트 표처럼 생긴 숫자형 행렬(Matrix)에서 열별/행별 가로/세로 데이터 총량 평균을 단타로 구하고 싶다면? 👉 무조건 원조 apply
– 여러 윈도우 폴더에 파편처럼 흩어져 묶인 100개의 데이터 뭉치 리스트(List) 구조를 부수지 않고, 내부 원본에 똑같은 계산 체인만 일괄 파괴 적용해 다시 기존의 길다란 바구니 모양에 고스란히 돌려 담고 싶다면? 👉 lapply
– 똑같이 데이터 서랍장들을 계산 적용하되, 결과물 프린팅이 껍질 다 버리고 숫자형 결과값만 한 줄 횡렬로 아주 시크하고 깔끔한 벡터(Vector)로 떨어져서 그래프 그리는데 바로 쓰고 싶다면? 👉 sapply

이 위대한 apply 계열의 베이스 함수 3대장 구조들은 for 문이 가진 연산 딜레이를 파괴하고 메모리 로드 연산 속도를 포르쉐급으로 끌어올려주는 빅데이터 핸들링의 주역입니다. 처음엔 영문 이름 구분이 낯설더라도 꼭 콘솔에서 손으로 직접 쳐보고 차이를 뼛속까지 익숙해지길 강력히 권장합니다.


당신이 좋아할 만한 콘텐츠

by Google Adsense


관련 글 보기