이전 파트의 마지막 부분에서 간단한 한 줄 변환을 수행하기 위해 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