1. 리콜 상세내역 데이터 긁어오기

미국 도로교통안전국(NHTSA)은 미국에서 시판되는 자동차에 대한 리콜 및 고객불만 데이터를 NHTSA Office of Defects Investigation (ODI) - Recalls 웹API를 통해서 제공하고 있다.

R 팩키지도 공개되어 있어 openNHTSA를 통해서 별도 RESTful API 프로그래밍을 생략하고 R 코드로 자동차 리콜과 고객불만 데이터를 긁어올 수 있다.

NHTSA - 현대기아차 리콜과 불만 추세(2001-2017)에서 현대기아차 자동차 리콜 추세를 살펴보기 위한 상위수준 데이터를 긁어왔다면, 이번에는 동일한 기간 2001-2017 리콜에 대한 상세 내역을 긁어와서 분석을 추가로 추진한다.

2. 현대기아차 리콜 상세내역 데이터 긁어오기

2.1. 리콜데이터 추출 환경설정

openNHTSA 예제 코드를 참조하여 2001-2017년까지 현대차와 기아차에 대한 리콜과 불만 데이터을 위한 설정을 준비한다.

crawl_nhtsa() 함수를 통해 차량모델(vehicle_model()) 함수에 넣을 차량모델을 추출하고 나서, 이를 crawl_nhtsa_detail() 함수에 넣어 리콜 및 고객불만에 대한 상세 내역을 웹API를 통해 가져온다.

# 0. 환경설정 ----------------
## 1.0. NHTSA 데이터 긁어오기

### 1.0.1. 제조사별, 리콜, 고객불만 모형 데이터
crawl_nhtsa <- function(maker, recall_complaint) {
  
  nhtsa_df <- data.frame()
  
  for(myear in 2001:2017) {
    tmp_df <- facility(recall_complaint) %>%
      model_year(myear) %>%
      vehicle_make(maker) %>% 
      nhtsa_fetch()
    nhtsa_df <- bind_rows(nhtsa_df, tmp_df)
  }
  return(nhtsa_df)
}

### 1.0.2. 리콜, 고객불만 상세 데이터
crawl_nhtsa_detail <- function(maker, recall_complaint, model) {
  
  nhtsa_df <- data.frame()
  
  for(myear in 2001:2017) {
    tmp_df <- facility(recall_complaint) %>%
      model_year(myear) %>%
      vehicle_make(maker) %>% 
      vehicle_model(model) %>% 
      nhtsa_fetch()
    nhtsa_df <- bind_rows(nhtsa_df, tmp_df)
  }
  return(nhtsa_df)
}

2.2. 리콜데이터 추출

먼저 현대자동차 리콜(“recalls”)에 대한 상세 내역을 가져오고 나서, 고객불만(“complaints”) 데이터도 가져온다.

# 1. 현대차 리콜, 고객불만 데이터 가져오기 ----------------
## 1.1. 현대차 모델 뽑아내기
hyundai_df <- crawl_nhtsa("hyundai", "recalls")
hyundai_model_v <- hyundai_df %>% count(Model) %>% pull(Model)

## 1.2. 현대차 리콜 상세 데이터 긁어오기
# 2001년부터 현대차 리콜 상세 내역
hyundai_recall_df <- data.frame()

for(i in seq_along(hyundai_model_v)){
  tmp_df <- crawl_nhtsa_detail("hyundai", "recalls", hyundai_model_v[i]) 
  hyundai_recall_df <- bind_rows(hyundai_recall_df, tmp_df)
  cat(i, ":", hyundai_model_v[i], "\n")
}

saveRDS(hyundai_recall_df, "data/hyundai_recall_df.rds")

## 1.3. 현대차 고객불만 상세 데이터 긁어오기
# 2001년부터 현대차 고객불만 상세 내역
hyundai_complaint_df <- data.frame()

for(i in seq_along(hyundai_model_v)){
  tmp_df <- crawl_nhtsa_detail("hyundai", "complaints", hyundai_model_v[i]) 
  hyundai_complaint_df <- bind_rows(hyundai_complaint_df, tmp_df)
  cat(i, ":", hyundai_model_v[i], "\n")
}

saveRDS(hyundai_complaint_df, "data/hyundai_complaint_df.rds")

이어서 기아자동차 리콜(“recalls”)에 대한 상세 내역을 가져오고 나서, 고객불만(“complaints”) 데이터도 가져온다.

# 2. 기아차 리콜, 고객불만 데이터 가져오기 ----------------
## 2.1. 기아차 모델 뽑아내기
kia_df <- crawl_nhtsa("kia", "recalls")
kia_model_v <- kia_df %>% count(Model) %>% pull(Model)

## 2.2. 기아차 리콜 상세 데이터 긁어오기
# 2001년부터 기아차 리콜 상세 내역
kia_recall_df <- data.frame()

for(i in seq_along(kia_model_v)){
  tmp_df <- crawl_nhtsa_detail("kia", "recalls", kia_model_v[i]) 
  kia_recall_df <- bind_rows(kia_recall_df, tmp_df)
  cat(i, ":", kia_model_v[i], "\n")
}

saveRDS(kia_recall_df, "data/kia_recall_df.rds")

## 2.3. 기아차 고객불만 상세 데이터 긁어오기
# 2001년부터 기아차 고객불만 상세 내역
kia_complaint_df <- data.frame()

for(i in seq_along(kia_model_v)){
  tmp_df <- crawl_nhtsa_detail("kia", "complaints", kia_model_v[i]) 
  kia_complaint_df <- bind_rows(kia_complaint_df, tmp_df)
  cat(i, ":", kia_model_v[i], "\n")
}

saveRDS(kia_complaint_df, "data/kia_complaint_df.rds")

3. 현대기아차 리콜 고장부품 데이터

3.1. 현대기아차 리콜 내역 데이터 준비

현대차 리콜 hyundai_recall_df, 기아차 리콜 kia_recall_df을 합하여 recall_df 분석용 데이터를 준비한다.

## 1.3. 리콜 데이터
recall_df <- bind_rows(hyundai_recall_df, kia_recall_df)

3.2. 현대기아차 리콜 내역 데이터 전처리

현대기아차 북미 NTHSA에서 리콜 부품에 대해서 BOM 위계체계를 갖는 형태로 데이터를 제공하기 하기 때문에 가장 상단 시스템 수준에 대한 고장부품/시스템에 대해서 분석을 하기 위해서 일정부분 전처리가 필요하다.

또한, 리콜 당시 한가지 부품만 문제가 되는 것이 아니라 다수 부품이 문제가 되기 때문에 이에 대해서도 적절한 데이터 정제과정을 거쳐 깔끔하게 정리한다.

# 2. 탐색적 데이터 분석 -------------
## 2.1. BOM 수준별 정리
bom_part_df <- recall_df %>% 
  count(Component, sort=TRUE) %>% 
  mutate(bom = str_split(Component, "\\|")) %>% 
  unnest(bom) %>% 
  mutate(part = str_split(bom, ":")) %>% 
  mutate(level = map_int(part, length)) %>% 
  unnest(part) %>% 
  mutate(part = str_trim(part)) #처음과 끝 공백 제거

## 2.2. BOM 최상위 수준
bom_system_df <- bom_part_df %>% group_by(Component, bom, level) %>% 
  summarise(system_part = first(part),
            recall_cnt = first(n)) %>% 
  ungroup() %>% 
  select(Component, system_part, recall_cnt)

3. 현대기아차 리콜 고장부품 분석

3.1. 자동차 모델별 리콜 표

가장 먼저 현대기아차 모델별 리콜 횟수를 표로 도식화한다.

# 3. 리콜 자동차 부품 표/시각화 -------------
## 3.1. 자동차 모델
recall_df %>% count(Model, sort=TRUE) %>% 
  mutate(비율 = n/ sum(n),
         누적비율 = cumsum(비율)) %>% 
  select(차량모델=Model, 리콜횟수=n, everything()) %>% 
  DT::datatable() %>% 
  DT::formatPercentage(c("비율", "누적비율"), digits=1)

3.2. 자동차 부품별 리콜표

다음으로 현대기아차 부품별로 가장 많은 리콜을 일으킨 부위를 표로 정리한다.

## 3.1. 리콜 자동차 부품
bom_system_df %>% group_by(system_part) %>% 
  summarise(recall_sum = sum(recall_cnt)) %>% 
  arrange(desc(recall_sum)) %>% 
  mutate(비율 = recall_sum/ sum(recall_sum),
         누적비율 = cumsum(비율)) %>% 
  DT::datatable() %>% 
    DT::formatPercentage(c("비율", "누적비율"), digits=1)

3.3. 자동차 부품별 리콜 상세표

현대기아차 차량모델, 부품별을 표로 작성하여 살펴면 다음과 같다.

## 3.3. 자동차 모델과 리콜 자동차 부품
recall_component_model_df <- recall_df %>% select(Make, Model, ModelYear, Component) %>% 
  mutate(bom = str_split(Component, "\\|")) %>% 
  unnest(bom) %>% 
  mutate(system_part = ifelse(str_detect(bom, ":"), str_extract(bom, "(^.*):"), bom)) %>% 
  mutate(system_part = str_trim(str_replace_all(system_part, ":", "")))

recall_component_model_df %>% 
  count(Model, system_part, sort=TRUE) %>% 
  mutate(비율 = n/ sum(n)) %>% 
  select(차량모델=Model, 고장부품=system_part, 리콜횟수=n, everything()) %>% 
  DT::datatable() %>% 
  DT::formatPercentage(c("비율"), digits=1)

3.4. 자동차 부품별 리콜 상세 데이터

현대기아차 차량모델, 부품별로 리콜 상세 내역을 차량 출시 연도와 함께 표로 살펴볼 수 있도록 정리한다.

recall_component_model_df %>% 
  select(-bom) %>% 
  DT::datatable()