매출 DB에서 프로모션 대상 상품을 구매한 고객을 찾아내고자 한다. R을 활용해서 어떻게 해결할 수 있는지 알아보자.
데이터 준비
다음과 같이 데이터가 있다고 하자.
● ID
: 고객 ID
● Prod
: 구매 제품명
1 | df = data.frame(ID = c("3912A41", "3912A41", "4353B21", "4353B21", "4353B21", "REG1242", "REG1242", "ADM1239"), |
문제 상황
프로모션 대상 상품인 사과와 바나나라고 해당 제품을 구매한 사람을 찾아내고자 한다.
풀이
단순히 특정 상품을 구매한 경우를 생각할 수 있으나 이는 다음과 같이 세 가지 경우의 수가 있다.
● 프로모션 상품을 하나라도 구매한 경우
● 프로모션 상품을 모두 구매한 경우
● 프로모션 상품만 구매한 경우
각 상황에 따라 어떻게 코드를 작성하는지 알아보자.
프로모션 상품을 하나라도 구매한 경우
먼저 프로모션 상품인지 아닌지 구분하는 “is_target” 변수를 만들어보자. 이 때 ifelse()
함수를 활용할 수 있지만 논리값(TRUE
, FALSE
)의 속성을 활용해 결과에 0을 더해 숫자로 자동 형변환이 되도록 했다.
1 | df[, "is_target"] = (df$Prod %in% c("사과", "바나나")) + 0 |
상품을 하나라도 구매했으면 1만 있고, 그렇지 않은 경우 0만 있기 때문에 최대값을 알아보는 방식으로 접근할 수 있으며 코드는 다음과 같다.
1 | aggregate(data = df, is_target ~ ID, FUN = "max") |
프로모션 상품을 모두 구매한 경우
프로모션 상품이 2개이기 때문에 “is_target” 변수의 합이 2인 경우를 확인하면 되고, 코드는 다음과 같다.
1 | aggregate(data = df, is_target ~ ID, FUN = "sum") |
lambda 함수로 한 번에 처리하는 코드는 다음과 같다.
1 | aggregate(data = df, is_target ~ ID, FUN = function(x){(sum(x) == 2) + 0}) |
단, 현재 데이터가 특정 상품을 한 번만 구매한것과 같은 형식이기 때문에 실제 데이터에서 이 형식으로 만들고자 할 경우 unique()
같은 함수로 중복제거를 먼저 실시해야 하겠다.
프로모션 상품만 구매한 경우
문제 해결을 위한 여러 버전의 코드가 있을 수 있는데 핵심은 각 고객의 row 개수와 프로모션 상품을 구매한 개수가 같아야 한다는 것이다. 파생변수를 활용한 방법을 먼저 알아보자.
1 | df[, "cnt"] = 1 |
상기 코드 중 ifelse()
함수의 “test” 인자에 조건을 2개 지정했는데 이 부분을 잘 보아야 한다. 첫 번째 조건을 생략한다면 프로모션 상품만 구매한 것을 골라낼 수 있긴 하지만 모든 프로모션 상품을 구매한 사람을 걸러낼 수 없다.
이번엔 “is_target” 변수를 활용하지 않고 사용자 정의 함수를 활용하여 해결해보자.
1 | target_checker = function(x){ |
사용자 정의 함수를 좀 더 고도화 해보자. 프로모션 상품이 반드시 2개라는 보장이 없기 때문에 사용자 정의 함수의 입력에 “prods” 인자를 추가하여 프로모션 상품 정보를 입력받도록 한 target_checker_v2()
함수를 사용한 예제는 다음과 같다.
1 | target_checker_v2 = function(x, prods){ |