HOWTO · R

R에서 여러 인수로 함수 적용

이 튜토리얼은 R에서 여러 인수로 함수를 적용하는 방법을 보여줍니다.

이 페이지의 내용

R에서 여러 인수를 받는 함수를 적용하려면 apply() 또는 lapply() 뒤에 고정 값을 전달하고, mapply() 또는 Map()에는 서로 대응하는 값이 담긴 벡터를 전달합니다. 입력 형태와 리스트 결과가 필요한지, 단순화된 결과가 필요한지에 따라 함수를 선택하세요.

apply 함수에 추가 인수 전달하기

apply(X, MARGIN, FUN, ...)은 배열의 각 부분에 FUN을 적용합니다. 행렬에서 MARGIN = 1은 행을, MARGIN = 2는 열을 선택합니다. FUN 뒤에 오는 인수는 해당 함수에 전달되므로, 처리하는 부분이 바뀌어도 고정된 값을 사용할 수 있습니다. 같은 방식은 lapply(X, FUN, ...)에도 적용됩니다. 이 함수는 리스트의 각 요소에 FUN을 한 번씩 호출하고 항상 리스트를 반환합니다. sapply()도 요소별로 함수를 적용하지만, 가능하면 리스트 결과를 벡터나 행렬로 단순화하려고 합니다. 본질적으로 더 빠른 함수는 아닙니다.

다음 예제를 실행해 보세요.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

scores <- matrix(1:6, nrow = 2)
row_totals <- apply(scores, MARGIN = 1, FUN = function(row, scale, offset) {
  sum(row * scale + offset)
}, scale = 2, offset = 1)
print(row_totals)
[1] 21 27

각 행은 row로 함수에 전달되며, scale과 offset은 각각 2와 1로 고정되어 있습니다. apply()는 배열에 사용하도록 설계되었습니다. 데이터 프레임에 사용하면 열이 공통 유형으로 강제 변환될 수 있습니다. 리스트 요소와 각 요소의 유형을 유지해야 한다면 lapply() 또는 Map()을 사용하세요.

mapply로 병렬 인수 처리하기

각 함수 호출에 여러 입력의 같은 위치에 있는 값을 전달하려면 mapply(FUN, ..., MoreArgs = NULL, SIMPLIFY = TRUE)를 사용하세요. apply()와 달리 행렬의 행이나 열을 선택하지 않습니다. MoreArgs로 전달한 값은 모든 호출에서 고정되고, ...로 전달한 값은 호출마다 달라집니다. 기본적으로 mapply()는 sapply()처럼 결과를 단순화하려고 합니다.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

add_with_tax <- function(price, tax, rate) price * (1 + rate) + tax
prices <- c(10, 20, 30)
fees <- c(1, 2, 3)
totals <- mapply(add_with_tax, prices, fees, MoreArgs = list(rate = 0.1))
print(totals)
[1] 12 24 36

이 예제에서는 각 가격이 같은 위치의 수수료와 짝을 이루고, 세율은 고정되어 있습니다. 입력 길이가 다르면 mapply()는 R의 벡터 재활용 규칙에 따라 입력을 재활용합니다. 각 항목이 하나씩 정확히 짝을 이루어야 한다면 입력 길이를 같게 하세요. 리스트 결과가 더 적합하다면 SIMPLIFY = FALSE로 설정하세요.

리스트 결과가 필요할 때 Map 사용하기

Map(FUN, ...)은 입력에서 서로 대응하는 요소에 FUN을 적용하고 리스트를 반환합니다. 단순화를 사용하지 않도록 설정한 mapply()와 같으므로, 각 호출의 결과를 서로 독립된 리스트 요소로 유지해야 할 때 적합합니다.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

combine <- function(values, multiplier) values * multiplier
parts <- list(first = 1:2, second = 3:4)
scaled <- Map(combine, parts, c(10, 100))
print(scaled)
$first
[1] 10 20

$second
[1] 300 400

각 리스트 요소는 같은 위치의 곱셈 인수와 함께 전달됩니다. 요소들을 벡터나 행렬로 합칠 수 있는 경우에도 이 함수는 리스트를 반환합니다. mapply()와 마찬가지로 Map()은 길이가 짧은 입력을 재활용하므로, 위치별 대응이 중요하다면 입력 길이를 확인하세요.

적절한 apply 계열 함수 선택하기

  • 고정된 추가 인수를 FUN 뒤에 전달하면서 행렬이나 다른 배열의 행 또는 열을 처리하려면 apply()를 사용하세요.
  • 입력 리스트 하나를 처리하고 결과를 항상 리스트로 유지하려면 lapply()를 사용하세요. 결과를 단순화하려는 동작이 유용하고 결과 형태도 적절하다면 sapply()를 사용하세요.
  • 여러 입력에서 서로 대응하는 요소를 각 함수 호출의 인수로 전달하려면 mapply()를 사용하세요. 결과를 리스트로 받아야 한다면 SIMPLIFY = FALSE로 설정하세요.
  • 같은 병렬 입력 방식을 사용하되 기본적으로 리스트 결과가 필요하다면 Map()을 사용하세요.

네 경우 모두 적용할 함수의 일반 인수가 먼저 오며, 고정 값의 역할을 분명히 하는 데 도움이 된다면 이름을 지정하세요. mapply()와 Map()에서는 입력 재활용 방식이 의도한 짝짓기와 일치하는지 확인하세요. apply()의 경우 데이터 프레임을 처리하기 전에 데이터 프레임이 강제 변환될 수 있다는 점을 기억하세요. 이런 동작 차이를 기준으로 함수를 선택하는 편이 막연한 속도 주장에 기대는 것보다 유용합니다.