우리가 매번 R을 켜고 데이터 분석을 진행하면서 숨 쉬듯 쉽고 당연하게 입력하는 sum(), mean(), 혹은 seq() 조차도 과거 누군가가 R 코어 생태계 패키지를 만들며 피땀 흘려 코딩해 놓은 “미리 만들어진 명령어 꾸러미”입니다. 그런데 세상에 존재하는 그 수많은 함수가 내 특수한 비즈니스 입맛에 딱 맞게 100% 짜여 있을 리는 없겠죠?
여러 단계의 복잡한 데이터 전처리나 특수한 수식 산출 작업을 반복해야 하다 보면 자연스레 나만의 맞춤형 명령어 시스템이 절실해집니다. 이럴 때 R 내장 예약어인 function() 을 사용하여 내 아이디어를 관통하는 나만의 사용자 정의 함수(User Defined Function)를 만들어버리면 작업 효율이 100배로 뜁니다. 오늘은 함수 생성 공장의 가장 핵심 가이드라인을 마스터해 봅니다.
1. 사용자 정의 함수의 3대 구성 요소
R에서 구조적인 커스텀 함수를 직접 정의하고 싶을 땐 무조건 아래의 3단 뼈대 로직을 외우고 있어야 합니다.
내가_지어준_함수_이름 <- function(입력값_재료) {
# 여기서 입력값을 지지고 볶고 어떻게 요리할 것인지 세부 코드 작성!
# (결과물 임시 저장소 생성)
return(결과물)
}
- 함수 이름: 내가 앞으로 평생 R 편집기에서 호출하기 위해 칠 영단어입니다.
- 입력 파라미터(Arguments): 사용자가 함수를 호출할 때 블랙박스 내부로 던져줄 재료 변수 역할을 합니다.
- 내용 구문(Body) & 반환(Return): 입력된 데이터를 가공하는 핵심 알고리즘 이후, 계산된 결과를
return()을 통해 함수 바깥 세상으로 예쁘게 뱉어줍니다.
실전 예제: 무조건 두 개 숫자를 더해주는 덧셈기록원!
실제 즉각 작동하는 코드로 add_two_numbers()라는 나만의 함수를 설계해 봅시다.
# 함수 선언 및 정의부
add_two_numbers <- function(a, b) {
result <- a + b
return(result)
}
위 블록을 구동시켜 메모리에 함수를 선언해두고 나면, 이제 여러분의 콘솔창에서 방금 만든 함수를 당당하게 호출하여 사용할 수 있는 마법이 펼쳐집니다.
# 정의한 내 함수 사용해보기
add_two_numbers(5, 10)
> [1] 15
2. 입력 안 했을 때 당황 금지! 기본 입력값(Default) 설정
함수를 쓸 때 괄호 안에 재료(입력값)를 누락하고 던져버리면 “기본값이 없습니다” 하면서 프로그램에 치명적인 에러가 발생합니다. 하지만, 함수를 설계하는 단계에서부터 “만약 이 게으른 녀석이 재료를 넘기지 않으면 평소엔 그냥 이걸로 요리해”라고 디폴트값 세팅을 박아둘 수 있습니다.
# x의 기본값을 3으로 든든하게 지정해 둔 함수
g <- function(x = 3) {
result <- x + 1
return(result)
}
# 괄호 안에 아무런 값을 넣지 않고 호출!
g()
> [1] 4
보이시나요? 여러분이 귀찮아서 빈 괄호 g() 만 넘겼음에도 불구하고 엔진은 알아서 “아, 3을 디폴트로 주기로 했지?” 하고 내부적으로 3 + 1 을 계산해 통과시켜 줍니다.
3. Tidyverse 스타일, 멋진 R 개발자의 2가지 코딩 규칙!
전세계 R 개발자들이 제일 선호하는 스타일 가이드라인을 지켜서 코딩하면 동료들이 보기에 훨씬 더 깔끔하고 전문가스럽게 보일 수 있습니다.
첫째, 제일 마지막엔 return() 안 써도 돼!
R의 함수 프로세서는 타 언어에 비해 진짜 똑똑해서 가장 마지막 줄에 혼자 덩그러니 놓인 계산 결괏값이나 객체를 무조건 자동으로 반환(Return)해 주도록 코어 설계가 되어 있습니다. 그래서 굳이 구식 문법처럼 return(결과) 이라고 명시적으로 쓰는 것을 생략하는 것이 오히려 Modern R스러운 코딩입니다.
# 훌륭한 예 (간결하고 세련됨)
add_two <- function(x, y) {
x + y # 마지막 수식이자 줄이므로 자동으로 튀어나갑니다.
}
# 파이썬/C언어 방식이 남은 예 (초보자 느낌)
add_two_old <- function(x, y) {
return(x + y)
}
(단, 예외 사항이 있습니다. 만약 로직 중간에 에러나 특정 조건을 감지하여 도중에 함수를 일찍 강제 종료하고 탈출시켜버려야 할 때는 Early Return 구문으로써 return()을 명시적으로 적어주어야 합니다!)
둘째, 함수 이름 작명 시 불문율 지키기
- 대문자 쓰지 마세요: 무조건 소문자와 숫자, 그리고 이들을 연결하는 밑줄(
_)로만 결합하는 스네이크 케이스(Snake Case)를 강력히 권고합니다. - 점(
.) 쓰지 마세요: 타 언어의 객체 상속 문법이자 기본 R 클래스 정의 구조(S3 method)에서 점을 예약어처럼 사용하므로 충돌을 막기 위해 띄어쓰기 용도로 점을 쓰면 절대 안 됩니다. - 명사가 아닌 동사로 지으세요: 일반 저장 변수는 명사(
user_data,final_score)로 짓지만, 함수는 능동적인 행동을 뜻하므로 동사(calculate_sum,clean_text)로 시작하여 짓는 게 암묵적 국룰입니다.
# 칭찬받는 함수 네이밍
add_two_numbers()
extract_unique_keys()
# 선임에게 혼나는 극혐 네이밍들
AddTwo() # 으악 대문자 카멜 케이스 통일성 파괴
number_adder() # 으악 함수는 행위인데 명사로 적음
my.test.func() # 으악 R 내장 메소드랑 충돌 우려
이제 코딩을 하다가 복잡한 포맷팅이나 데이터 작업이 2번, 3번 이상 거듭 발생한다면 귀찮게 복사 붙여넣기로 하드코딩 하지 마시고 function()을 선언하고 상단에 배치하여 나만의 전용 오토공장 시스템을 갖춰보세요!
당신이 좋아할 만한 콘텐츠
by Google Adsense