데이터 인사이트 스터디 내용을 관리하는 블로그 입니다.

Data Insight Study Blog

  • Join Us on Facebook!
  • Follow Us on Twitter!
  • LinkedIn
  • Subcribe to Our RSS Feed

2. Reading and Preparing Data > Preparing the Data > Complex Transformations

복잡한 변환

이전 파트의 마지막 부분에서 간단한 한 줄 변환을 수행하기 위해 rxDataStep이 소개 되었습니다. 이제 다시 rxDataStep을 사용하여 다른 변환을 수행하여 봅시다. 이번에는 보다 복잡한 변환을 수행합니다. 위의 예제에서와 같이, 때로는 transforms 인수를 사용하여 좀 더 복잡한 변환을 더 길게 작성된 단일 행으로써 수행할 수도 있습니다. 그러나 보다 더 깔끔한 방법은 변환 로직을 포함하는 함수를 만들어 transformFunc 인수에 전달하는 것입니다. 이 함수는 특정 데이터를 입력으로 사용하고 일반적으로 하나 이상의 열이 추가되거나 수정된 출력과 동일한 데이터를 반환합니다. 보다 구체적으로 말하자면, 변환 함수에 대한 입력은 요소가 열인 목록(list)이 됩니다. 이를 제외한 나머지 부분은 통상적인 R의 함수와 동일합니다. transformFunc 인수를 사용하면 변환 함수의 작성에만 집중할 수 있기 때문에, 전체 데이터에서 실행하기 전에 샘플 data.frame에서 신속하게 기능을 테스트 할 수 있습니다.

뉴욕 택시 데이터에서, 우리는 요일 및 시간대를 기준으로 한 운행 내역들을 비교하고 싶습니다. 이 두 열은 아직 존재하지 않지만, 탑승 날짜와 시간 및 하차 날짜와 시간에서 추출할 수 있습니다. 위의 특성(feature)들을 추출하기 위해, 우리는 날짜 및 시간 열을 처리하는 데 유용한 함수가 포함되어 있는 lubridate 패키지를 사용합니다. 변환을 수행하기 위해 xforms라는 변환 함수를 사용합니다.

xforms <- function(data) { # 날짜 및 시간 특성 추출을 위한 변환 함수
  
  weekday_labels <- c('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat')
  cut_levels <- c(1, 5, 9, 12, 16, 18, 22)
  hour_labels <- c('1AM-5AM', '5AM-9AM', '9AM-12PM', '12PM-4PM', '4PM-6PM', '6PM-10PM', '10PM-1AM')
  
  pickup_datetime <- ymd_hms(data$tpep_pickup_datetime, tz = "UTC")
  pickup_hour <- addNA(cut(hour(pickup_datetime), cut_levels))
  pickup_dow <- factor(wday(pickup_datetime), levels = 1:7, labels = weekday_labels)
  levels(pickup_hour) <- hour_labels
  
  dropoff_datetime <- ymd_hms(data$tpep_dropoff_datetime, tz = "UTC")
  dropoff_hour <- addNA(cut(hour(dropoff_datetime), cut_levels))
  dropoff_dow <- factor(wday(dropoff_datetime), levels = 1:7, labels = weekday_labels)
  levels(dropoff_hour) <- hour_labels
  
  data$pickup_hour <- pickup_hour
  data$pickup_dow <- pickup_dow
  data$dropoff_hour <- dropoff_hour
  data$dropoff_dow <- dropoff_dow
  data$trip_duration <- as.integer(as.duration(dropoff_datetime - pickup_datetime))
  
  data
}

변환을 데이터에 적용하기 전에 데이터를 테스트 하고 변환이 올바르게 작동하는지를 확인하는 것이 좋습니다. 우리는 이러한 목적으로 데이터의 샘플을 따로 때어내어, data.frame으로 저장합니다. nyc_sample_df에 변환 함수를 실행하면, 원래 데이터에 새로운 열이 추가된 데이터가 반환됩니다.

library(lubridate)
Sys.setenv(TZ = "US/Eastern") # 이 데이터셋에는 중요하지 않음 
head(xforms(nyc_sample_df)) # data.frame에 대하여 변환을 테스트
  VendorID tpep_pickup_datetime tpep_dropoff_datetime passenger_count trip_distance
1        2  2016-01-01 00:00:00   2016-01-01 00:00:00               2          1.10
2        2  2016-01-01 00:00:00   2016-01-01 00:00:00               5          4.90
3        2  2016-01-01 00:00:00   2016-01-01 00:00:00               1         10.54
4        2  2016-01-01 00:00:00   2016-01-01 00:00:00               1          4.75
5        2  2016-01-01 00:00:00   2016-01-01 00:00:00               3          1.76
6        2  2016-01-01 00:00:00   2016-01-01 00:18:30               2          5.52
  pickup_longitude pickup_latitude RatecodeID store_and_fwd_flag dropoff_longitude
1        -73.99037        40.73470          1                  N         -73.98184
2        -73.98078        40.72991          1                  N         -73.94447
3        -73.98455        40.67957          1                  N         -73.95027
4        -73.99347        40.71899          1                  N         -73.96224
5        -73.96062        40.78133          1                  N         -73.97726
6        -73.98012        40.74305          1                  N         -73.91349
  dropoff_latitude payment_type fare_amount extra mta_tax tip_amount tolls_amount
1         40.73241            2         7.5   0.5     0.5          0            0
2         40.71668            1        18.0   0.5     0.5          0            0
3         40.78893            1        33.0   0.5     0.5          0            0
4         40.65733            2        16.5   0.0     0.5          0            0
5         40.75851            2         8.0   0.0     0.5          0            0
6         40.76314            2        19.0   0.5     0.5          0            0
  improvement_surcharge total_amount pickup_hour pickup_dow dropoff_hour
1                   0.3          8.8    10PM-1AM        Fri     10PM-1AM
2                   0.3         19.3    10PM-1AM        Fri     10PM-1AM
3                   0.3         34.3    10PM-1AM        Fri     10PM-1AM
4                   0.3         17.3    10PM-1AM        Fri     10PM-1AM
5                   0.3          8.8    10PM-1AM        Fri     10PM-1AM
6                   0.3         20.3    10PM-1AM        Fri     10PM-1AM
  dropoff_dow trip_duration
1         Fri             0
2         Fri             0
3         Fri             0
4         Fri             0
5         Fri             0
6         Fri          1110

변환을 적용하기 전에 마지막 테스트를 하나 실행합니다. rxDataStep은 data.frame 입력에서도 작동하며, outFile 인수를 지정하지 않고 남겨두면 data.frame을 반환한다는 것이 기억나시나요? 따라서 transform 함수를 transformFunc에 전달하고 transformPackages에 수행에 필요한 패키지를 지정하는 방식으로 rxDataStep을 사용하여 위의 테스트를 수행 할 수 있습니다.

head(rxDataStep(nyc_sample_df, transformFunc = xforms, transformPackages = "lubridate"))
Rows Processed: 1000 
  VendorID tpep_pickup_datetime tpep_dropoff_datetime passenger_count trip_distance
1        2  2016-01-01 00:00:00   2016-01-01 00:00:00               2          1.10
2        2  2016-01-01 00:00:00   2016-01-01 00:00:00               5          4.90
3        2  2016-01-01 00:00:00   2016-01-01 00:00:00               1         10.54
4        2  2016-01-01 00:00:00   2016-01-01 00:00:00               1          4.75
5        2  2016-01-01 00:00:00   2016-01-01 00:00:00               3          1.76
6        2  2016-01-01 00:00:00   2016-01-01 00:18:30               2          5.52
  pickup_longitude pickup_latitude RatecodeID store_and_fwd_flag dropoff_longitude
1        -73.99037        40.73470          1                  N         -73.98184
2        -73.98078        40.72991          1                  N         -73.94447
3        -73.98455        40.67957          1                  N         -73.95027
4        -73.99347        40.71899          1                  N         -73.96224
5        -73.96062        40.78133          1                  N         -73.97726
6        -73.98012        40.74305          1                  N         -73.91349
  dropoff_latitude payment_type fare_amount extra mta_tax tip_amount tolls_amount
1         40.73241            2         7.5   0.5     0.5          0            0
2         40.71668            1        18.0   0.5     0.5          0            0
3         40.78893            1        33.0   0.5     0.5          0            0
4         40.65733            2        16.5   0.0     0.5          0            0
5         40.75851            2         8.0   0.0     0.5          0            0
6         40.76314            2        19.0   0.5     0.5          0            0
  improvement_surcharge total_amount pickup_hour pickup_dow dropoff_hour
1                   0.3          8.8    10PM-1AM        Fri     10PM-1AM
2                   0.3         19.3    10PM-1AM        Fri     10PM-1AM
3                   0.3         34.3    10PM-1AM        Fri     10PM-1AM
4                   0.3         17.3    10PM-1AM        Fri     10PM-1AM
5                   0.3          8.8    10PM-1AM        Fri     10PM-1AM
6                   0.3         20.3    10PM-1AM        Fri     10PM-1AM
  dropoff_dow trip_duration
1         Fri             0
2         Fri             0
3         Fri             0
4         Fri             0
5         Fri             0
6         Fri          1110

모든 것이 잘 작동하는 것 같습니다. 전체 데이터 집합에 대해 변환 함수를 실행해도 데이터가 성공적으로 실행된다는 것을 100% 보장하는 것은 아니지만, 무언가 잘못 작성한 것 때문에실패할 것으로 보이지는 않습니다. 만약 위의 경우에서 처럼 변환이 샘플 data.frame에서는 잘 실행되었는데 전체 데이터 세트에서는 실패하였는 때에는, 이는 보통 샘플 데이터에는 존재하지 않는 전체 데이터 셋에서의 무언가의 원인(예 : 누락 된 값)으로 인해 발생합니다. 이제 전체 데이터 셋에 대하여 변환을 실행합니다.

st <- Sys.time()
rxDataStep(nyc_xdf, nyc_xdf, overwrite = TRUE, transformFunc = xforms, transformPackages = "lubridate")
Sys.time() - st
Time difference of 11.07041 mins
답글 기능이 비활성화되어 있습니다