데이터 사이언스 100번의 노크(구조화 데이터 처리편) – R Part 4 (Q61 to Q80)의 해설입니다.
참고(Reference) : 「데이터 사이언티스트 협회 스킬 정의 위원」의 「데이터 사이언스 100번의 노크(구조화 데이터 처리편)」입니다.
처음에
- 먼저 다음 셀을 실행합니다.
- 필요한 라이브러리를 가져오고 데이터베이스에서 데이터를 읽습니다(PostgreSQL).
- 사용할 것으로 예상되는 라이브러리는 다음 셀에서 가져옵니다.
- 사용하려는 다른 라이브러리가 있는 경우 install.packages()를 사용하여 적절하게 설치합니다.
- 이름, 주소 등은 더미 데이터이며 실제 데이터가 아닙니다.
require("RPostgreSQL")
require("tidyr")
require("dplyr")
require("stringr")
require("caret")
require("lubridate")
require("rsample")
require("recipes")
require("themis")
host <- "db"
port <- Sys.getenv()["PG_PORT"]
dbname <- Sys.getenv()["PG_DATABASE"]
user <- Sys.getenv()["PG_USER"]
password <- Sys.getenv()["PG_PASSWORD"]
con <- dbConnect(PostgreSQL(), host=host, port=port, dbname=dbname, user=user, password=password)
df_customer <- dbGetQuery(con,"SELECT * FROM customer")
df_category <- dbGetQuery(con,"SELECT * FROM category")
df_product <- dbGetQuery(con,"SELECT * FROM product")
df_receipt <- dbGetQuery(con,"SELECT * FROM receipt")
df_store <- dbGetQuery(con,"SELECT * FROM store")
df_geocode <- dbGetQuery(con,"SELECT * FROM geocode")
Loading required package: RPostgreSQL Loading required package: DBI Loading required package: tidyr Loading required package: dplyr Attaching package: ‘dplyr’ The following objects are masked from ‘package:stats’: filter, lag The following objects are masked from ‘package:base’: intersect, setdiff, setequal, union Loading required package: stringr Loading required package: caret Loading required package: ggplot2 Loading required package: lattice Loading required package: lubridate Attaching package: ‘lubridate’ The following objects are masked from ‘package:base’: date, intersect, setdiff, union Loading required package: rsample Loading required package: recipes Attaching package: ‘recipes’ The following object is masked from ‘package:stringr’: fixed The following object is masked from ‘package:stats’: step Loading required package: themis Registered S3 methods overwritten by 'themis': method from bake.step_downsample recipes bake.step_upsample recipes prep.step_downsample recipes prep.step_upsample recipes tidy.step_downsample recipes tidy.step_upsample recipes tunable.step_downsample recipes tunable.step_upsample recipes Attaching package: ‘themis’ The following objects are masked from ‘package:recipes’: step_downsample, step_upsample
연습문제
R-061: 영수증 내역 데이터(df_receipt)의 매출 금액(amount)을 고객 ID(customer_id)별로 합산하고, 매출 금액 합계를 상수 대수화(하단 10)하여 고객 ID, 매출 금액 합계와 함께 10건씩 표시한다. 단, 고객 ID가 “Z”로 시작하는 것은 비회원을 의미하므로 제외하여 계산한다.
df_receipt %>%
filter(!grepl("^Z", customer_id)) %>%
group_by(customer_id) %>%
summarise(sum_amount = sum(amount), .groups = "drop") %>%
mutate(log_amount = log((sum_amount + 0.5), base = 10)) %>%
slice(1:10)
customer_id | sum_amount | log_amount |
---|---|---|
<chr> | <int> | <dbl> |
CS001113000004 | 1298 | 3.113442 |
CS001114000005 | 626 | 2.796921 |
CS001115000010 | 3044 | 3.483516 |
CS001205000004 | 1988 | 3.298526 |
CS001205000006 | 3337 | 3.523421 |
CS001211000025 | 456 | 2.659441 |
CS001212000027 | 448 | 2.651762 |
CS001212000031 | 296 | 2.472025 |
CS001212000046 | 228 | 2.358886 |
CS001212000070 | 456 | 2.659441 |
설명:
이 코드는 df_receipt 데이터 프레임에 대해 다음과 같은 처리를 수행한다.
filter 함수를 사용하여 customer_id가 "Z"로 시작하는 행을 필터링합니다.
group_by 함수를 사용하여 customer_id별로 데이터를 그룹화합니다.
summarise 함수를 사용하여 합계를 취하여 각 고객 ID의 금액 열을 요약한다.
.groups = "drop" 인수를 사용하여 2단계에서 생성한 그룹을 삭제한다.
sum_amount의 로그에 0.5를 더한 값을 10진수로 표현한 log_amount라는 새로운 열을 생성한다.
slice 함수를 사용하여 결과 데이터 프레임에서 처음 10개의 행을 선택합니다.
전체적으로 이 코드는 df_receipt 데이터 프레임에 각 고객이 사용한 총 금액의 대수를 가진 새로운 열을 생성하며, 이는 왜곡된 데이터를 정규화하는 데 자주 사용되는 변환입니다.
R-062: 영수증 내역 데이터(df_receipt)의 매출금액(amount)을 고객ID(customer_id)별로 합산하고, 매출금액 합계를 자연대수화(하단 e)하여 고객ID, 매출금액 합계와 함께 10건씩 표시한다. 단, 고객 ID가 “Z”로 시작하는 것은 비회원을 의미하므로 제외하여 계산한다.
df_receipt %>%
filter(!grepl("^Z", customer_id)) %>%
group_by(customer_id) %>%
summarise(sum_amount = sum(amount), .groups = "drop") %>%
mutate(log_amount = log(sum_amount + 0.5)) %>%
slice(1:10)
customer_id | sum_amount | log_amount |
---|---|---|
<chr> | <int> | <dbl> |
CS001113000004 | 1298 | 7.168965 |
CS001114000005 | 626 | 6.440149 |
CS001115000010 | 3044 | 8.021092 |
CS001205000004 | 1988 | 7.595136 |
CS001205000006 | 3337 | 8.112977 |
CS001211000025 | 456 | 6.123589 |
CS001212000027 | 448 | 6.105909 |
CS001212000031 | 296 | 5.692047 |
CS001212000046 | 228 | 5.431536 |
CS001212000070 | 456 | 6.123589 |
설명:
이 코드는 df_receipt라는 데이터 프레임을 처리한다. 다음 단계를 수행합니다.
customer_id가 "Z"로 시작하는 행을 필터링합니다. 이는 dplyr 패키지의 filter() 함수와 조건으로 grepl() 함수를 사용하여 수행합니다.
dplyr 패키지의 group_by() 함수를 사용하여 나머지 행을 customer_id로 그룹화합니다.
금액 열의 sum() 함수를 사용하여 각 고객의 구매 금액 합계를 계산합니다. 이는 dplyr 패키지의 summarise() 함수를 사용하여 수행합니다.
sum_amount 열의 자연대수에 0.5를 더한 log_amount라는 새로운 열을 추가합니다. 이는 dplyr 패키지의 mutate() 함수와 베이스 R의 log() 함수를 사용하여 수행한다.
마지막으로 dplyr 패키지의 slice() 함수를 사용하여 결과 데이터 프레임의 처음 10개의 행을 선택한다.
R-063: 상품 데이터(df_product)의 단가(unit_price)와 원가(unit_cost)로부터 각 상품의 이익액을 산출하고, 그 결과를 10건 표시하시오.
df_product %>%
mutate(unit_profit = unit_price - unit_cost) %>%
slice(1:10)
product_cd | category_major_cd | category_medium_cd | category_small_cd | unit_price | unit_cost | unit_profit |
---|---|---|---|---|---|---|
<chr> | <chr> | <chr> | <chr> | <int> | <int> | <int> |
P040101001 | 04 | 0401 | 040101 | 198 | 149 | 49 |
P040101002 | 04 | 0401 | 040101 | 218 | 164 | 54 |
P040101003 | 04 | 0401 | 040101 | 230 | 173 | 57 |
P040101004 | 04 | 0401 | 040101 | 248 | 186 | 62 |
P040101005 | 04 | 0401 | 040101 | 268 | 201 | 67 |
P040101006 | 04 | 0401 | 040101 | 298 | 224 | 74 |
P040101007 | 04 | 0401 | 040101 | 338 | 254 | 84 |
P040101008 | 04 | 0401 | 040101 | 420 | 315 | 105 |
P040101009 | 04 | 0401 | 040101 | 498 | 374 | 124 |
P040101010 | 04 | 0401 | 040101 | 580 | 435 | 145 |
설명:
이 코드는 데이터 프레임 df_product를 받아 mutate() 함수를 사용하여 새로운 열 unit_profit을 생성하고, unit_profit 열은 df_product의 기존 열인 unit_price와 unit_cost의 차이로 계산됩니다. 합니다.
그리고 slice() 함수를 사용하여 새로운 unit_profit 열을 포함한 결과 데이터 프레임의 처음 10개의 행을 표시합니다.
R-064: 상품 데이터(df_product)의 단가(unit_price)와 원가(unit_cost)에서 각 상품의 전체 평균 수익률을 계산하시오. 단, 단가와 원가에는 결손이 발생한다는 점에 유의하라.
df_product %>%
mutate(unit_profit_rate = (unit_price - unit_cost) / unit_price) %>%
summarise(total_mean = mean(unit_profit_rate, na.rm = TRUE))
total_mean |
---|
<dbl> |
0.2491139 |
설명:
이 코드는 df_product라는 데이터 프레임에 대해 몇 가지 계산을 수행하고 있다.
mutate는 unit_profit_rate라는 새로운 열을 생성하는 데 사용되고 있다. 이 열은 단가에서 단가를 빼고 그 결과를 단가로 나누어 계산됩니다.
그런 다음 summarise 함수를 사용하여 unit_profit_rate 열의 평균을 계산합니다. 그 결과는 total_mean이라는 새로운 열에 할당됩니다.
요약하면, 이 코드는 df_product에서 판매된 제품의 각 단위당 평균 수익률을 계산하고 있는 셈이다.
R-065: 상품 데이터(df_product)의 각 상품에 대해 수익률이 30%가 되는 새로운 단가를 구하시오. 단, 1원 미만은 반올림한다. 그리고 10개의 결과를 표시하고, 수익률이 대략 30% 정도인 것을 확인하라. 단, 단가(unit_price)와 원가(unit_cost)에는 적자가 발생한다는 점에 유의하라.
df_product[c("product_cd", "unit_price", "unit_cost")] %>%
mutate(new_price = trunc(unit_cost / 0.7)) %>%
mutate(new_profit_rate = (new_price - unit_cost)/ new_price) %>% slice(1:10)
product_cd | unit_price | unit_cost | new_price | new_profit_rate |
---|---|---|---|---|
<chr> | <int> | <int> | <dbl> | <dbl> |
P040101001 | 198 | 149 | 212 | 0.2971698 |
P040101002 | 218 | 164 | 234 | 0.2991453 |
P040101003 | 230 | 173 | 247 | 0.2995951 |
P040101004 | 248 | 186 | 265 | 0.2981132 |
P040101005 | 268 | 201 | 287 | 0.2996516 |
P040101006 | 298 | 224 | 320 | 0.3000000 |
P040101007 | 338 | 254 | 362 | 0.2983425 |
P040101008 | 420 | 315 | 450 | 0.3000000 |
P040101009 | 498 | 374 | 534 | 0.2996255 |
P040101010 | 580 | 435 | 621 | 0.2995169 |
설명:
이 코드는 다음 단계를 수행한다.
데이터 프레임 "df_product"에서 "product_cd", "unit_price", "unit_cost" 열만 선택한다.
단가를 0.7로 나누고 그 결과를 가장 가까운 정수로 반올림하여 'new_price'라는 새로운 열을 생성한다. 이는 상품 가격을 일정 비율로 낮추기 위한 임의의 계산이다.
새 가격에서 단가를 빼고 그 결과를 새 가격으로 나누어 'new_profit_rate'라는 또 다른 새 열을 생성한다. 이것은 새로운 가격의 이익률을 계산하기 위한 것이다.
마지막으로 완성된 데이터 프레임에서 처음 10개의 행을 선택한다.
R-066: 상품 데이터(df_product)의 각 상품에 대해 수익률이 30%가 되는 새로운 단가를 구하시오. 이번에는 1원 미만은 반올림한다(반올림 또는 짝수로 반올림해도 무방하다). 그리고 10개의 결과를 표시하게 하고, 수익률이 대략 30% 정도인 것을 확인하라. 단, 단가(unit_price)와 원가(unit_cost)에는 결손이 발생한다는 점에 유의한다.
df_product[c("product_cd", "unit_price", "unit_cost")] %>%
mutate(new_price = round(unit_cost / 0.7)) %>%
mutate(new_profit_rate = (new_price - unit_cost) / new_price) %>%
slice(1:10)
product_cd | unit_price | unit_cost | new_price | new_profit_rate |
---|---|---|---|---|
<chr> | <int> | <int> | <dbl> | <dbl> |
P040101001 | 198 | 149 | 213 | 0.3004695 |
P040101002 | 218 | 164 | 234 | 0.2991453 |
P040101003 | 230 | 173 | 247 | 0.2995951 |
P040101004 | 248 | 186 | 266 | 0.3007519 |
P040101005 | 268 | 201 | 287 | 0.2996516 |
P040101006 | 298 | 224 | 320 | 0.3000000 |
P040101007 | 338 | 254 | 363 | 0.3002755 |
P040101008 | 420 | 315 | 450 | 0.3000000 |
P040101009 | 498 | 374 | 534 | 0.2996255 |
P040101010 | 580 | 435 | 621 | 0.2995169 |
설명:
이 코드는 상품 데이터 프레임(df_product)에 대해 몇 가지 계산을 수행한다.
먼저 "product_cd", "unit_price", "unit_cost" 세 개의 컬럼을 선택합니다.
이는 "unit_cost"를 0.7로 나눈 후(즉, 30% 비용 절감), round() 함수를 사용하여 가장 가까운 정수로 반올림하여 계산합니다.
다음으로 'new_profit_rate'라는 새로운 열을 생성한다. 이는 'new_price'에서 'unit_cost'를 빼고 그 결과를 'new_price'로 나누어 계산한다.
마지막으로 완성된 데이터 프레임의 처음 10개의 행을 선택하여 표시합니다.
이 코드는 기본적으로 생산 비용을 30% 절감했을 때 각 제품의 새로운 가격과 수익률을 계산한다.
R-067: 상품 데이터(df_product)의 각 상품에 대해 수익률이 30%가 되는 새로운 단가를 구하시오. 이번에는 1원 미만은 반올림한다. 그리고 10개의 결과를 표시하고, 수익률이 대략 30% 정도인 것을 확인하라. 단, 단가(unit_price)와 원가(unit_cost)에는 적자가 발생하고 있다는 점에 유의하라.
df_product[c("product_cd", "unit_price", "unit_cost")] %>%
mutate(new_price = ceiling(unit_cost / 0.7)) %>%
mutate(new_profit_rate = (new_price - unit_cost) / new_price) %>%
slice(1:10)
product_cd | unit_price | unit_cost | new_price | new_profit_rate |
---|---|---|---|---|
<chr> | <int> | <int> | <dbl> | <dbl> |
P040101001 | 198 | 149 | 213 | 0.3004695 |
P040101002 | 218 | 164 | 235 | 0.3021277 |
P040101003 | 230 | 173 | 248 | 0.3024194 |
P040101004 | 248 | 186 | 266 | 0.3007519 |
P040101005 | 268 | 201 | 288 | 0.3020833 |
P040101006 | 298 | 224 | 320 | 0.3000000 |
P040101007 | 338 | 254 | 363 | 0.3002755 |
P040101008 | 420 | 315 | 451 | 0.3015521 |
P040101009 | 498 | 374 | 535 | 0.3009346 |
P040101010 | 580 | 435 | 622 | 0.3006431 |
설명:
이 코드는 두 개의 새로운 변수 new_price와 new_profit_rate를 추가하여 df_product 데이터 프레임을 조작한다.
mutate(new_price = ceiling(unit_cost / 0.7))은 ceiling(unit_cost / 0.7)이라는 식의 결과를 포함하는 새로운 열 new_price를 생성하고, ceiling() 함수는 unit_cost / 0.7이라는 식의 결과를 가장 가까운 정수로 반올림합니다. 가장 가까운 정수로 반올림합니다. 그 결과 단가보다 30% 더 높은 새로운 가격이 됩니다.
mutate(new_profit_rate = (new_price - unit_cost) / new_price)는 새로운 열 new_profit_rate를 생성하고 (new_price - unit_cost) / new_price라는 식의 결과를 저장합니다. 이 식은 새로운 가격에서 이익이 차지하는 비율인 신수익률을 계산한다. 이는 신가격과 단가의 차이를 신가격으로 나눈 값으로 계산된다.
slice(1:10) 함수는 완성된 데이터 프레임의 처음 10개의 행을 표시하는 데 사용된다.
R-068: 상품 데이터(df_product)의 각 상품에 대해 소비세율 10%의 부가세 포함 금액을 구하고, 1원 미만의 단수는 절사하여 10개의 결과를 표시하시오. 단, 단가(unit_price)에는 결손이 발생한다는 점에 유의하라.
head(cbind(product_cd = df_product$product_cd,
df_product$unit_price,
tax_price = trunc(df_product$unit_price * 1.1)), 10)
product_cd | unit_price | tax_price |
---|---|---|
P040101001 | 198 | 217 |
P040101002 | 218 | 239 |
P040101003 | 230 | 253 |
P040101004 | 248 | 272 |
P040101005 | 268 | 294 |
P040101006 | 298 | 327 |
P040101007 | 338 | 371 |
P040101008 | 420 | 462 |
P040101009 | 498 | 547 |
P040101010 | 580 | 638 |
설명:
이 코드에서는 cbind 함수를 사용하여 df_product 데이터 프레임의 3개 열, 즉 product_cd, unit_price, tax_price를 새로운 데이터 프레임으로 결합한다. 그런 다음 head 함수를 사용하여 이 새로운 데이터 프레임의 첫 10개의 행을 표시한다.
새 데이터 프레임의 첫 번째 열은 product_cd로 표시되며, df_product의 product_cd 열의 값을 포함하고, 두 번째 열은 df_product$unit_price로 표시되며, df_product의 unit_price 열의 값이 저장되어 있습니다. 저장되어 있습니다.
세 번째 열은 tax_price라는 레이블로, unit_price 열의 각 값에 1.1을 곱한 결과에 trunc 함수를 적용하여 만들어졌다. 이는 10%의 세금이 포함된 제품 가격을 계산하는 것이다.
cbind 함수가 이미 df_product에서 unit_price 열을 추출했기 때문에 두 번째 열 이름에 df_product$를 사용할 필요가 없다는 점에 유의해야 한다.
R-069: 영수증 내역 데이터(df_receipt)와 상품 데이터(df_product)를 결합하여 고객별 전체 상품 판매금액 합계와 카테고리 대분류 코드(category_major_cd)가 “07”(병조림 통조림)인 상품의 판매금액 합계를 계산한 후, 양자의 비율을 구하시오. 추출 대상은 카테고리 대분류 코드 “07”(병조림 통조림)의 판매 실적이 있는 고객으로 한정하고, 결과를 10건만 표시한다.
# 코드 예제 1
df_tmp_1 <- df_receipt %>%
group_by(customer_id) %>%
summarise(sum_all=sum(amount))
df_tmp_2 <- inner_join(df_receipt, df_product[c("product_cd","category_major_cd")], by="product_cd") %>%
filter(category_major_cd == "07") %>% group_by(customer_id) %>%
summarise(sum_07 = sum(amount), .groups = "drop")
inner_join(df_tmp_1, df_tmp_2, by = "customer_id") %>%
mutate(sales_rate = sum_07 / sum_all) %>%
slice(1:10)
customer_id | sum_all | sum_07 | sales_rate |
---|---|---|---|
<chr> | <int> | <int> | <dbl> |
CS001113000004 | 1298 | 1298 | 1.0000000 |
CS001114000005 | 626 | 486 | 0.7763578 |
CS001115000010 | 3044 | 2694 | 0.8850197 |
CS001205000004 | 1988 | 346 | 0.1740443 |
CS001205000006 | 3337 | 2004 | 0.6005394 |
CS001212000027 | 448 | 200 | 0.4464286 |
CS001212000031 | 296 | 296 | 1.0000000 |
CS001212000046 | 228 | 108 | 0.4736842 |
CS001212000070 | 456 | 308 | 0.6754386 |
CS001213000018 | 243 | 145 | 0.5967078 |
해설:
# 코드 예시 2
본 코드는 다음과 같은 처리를 한다.
df_receipt 데이터 프레임의 각 고객이 사용한 금액의 합계를 계산하여 df_tmp_1에 저장한다.
df_receipt 데이터 프레임과 df_product 데이터 프레임을 product_cd로 결합하여 category_major_cd가 '07'인 행만 필터링한다.
필터링된 데이터 프레임의 각 고객별 금액 열의 합계를 계산하여 df_tmp_2에 저장한다.
df_tmp_1과 df_tmp_2 데이터 프레임을 customer_id로 결합한다.
각 고객의 메이저 코드 "07"의 판매율을 계산하여 sales_rate라는 새로운 컬럼에 저장한다.
결과 데이터 프레임을 슬라이스하여 처음 10개의 행을 표시한다.
inner_join 함수는 공통 변수로 데이터 프레임을 결합하는 데 사용되며, mutate 함수는 기존 열을 기반으로 계산된 새로운 열을 데이터 프레임에 추가하고, slice 함수는 데이터 프레임에서 행의 하위 집합을 추출하는 데 사용된다.
# 코드 예시 2 (%>%로 모든 처리 연결)
inner_join(df_receipt, df_product[c("product_cd","category_major_cd")], by="product_cd") %>% filter(category_major_cd == "07") %>%
group_by(customer_id) %>%
summarise(sum_07 = sum(amount), .groups = "drop") %>%
inner_join(df_receipt, by="customer_id") %>%
group_by(customer_id) %>%
summarise(sum_all=sum(amount), sum_07=max(sum_07), .groups = "drop") %>%
mutate(sales_rate = sum_07 / sum_all) %>%
slice(1:10)
customer_id | sum_all | sum_07 | sales_rate |
---|---|---|---|
<chr> | <int> | <int> | <dbl> |
CS001113000004 | 1298 | 1298 | 1.0000000 |
CS001114000005 | 626 | 486 | 0.7763578 |
CS001115000010 | 3044 | 2694 | 0.8850197 |
CS001205000004 | 1988 | 346 | 0.1740443 |
CS001205000006 | 3337 | 2004 | 0.6005394 |
CS001212000027 | 448 | 200 | 0.4464286 |
CS001212000031 | 296 | 296 | 1.0000000 |
CS001212000046 | 228 | 108 | 0.4736842 |
CS001212000070 | 456 | 308 | 0.6754386 |
CS001213000018 | 243 | 145 | 0.5967078 |
설명:
이 코드는 카테고리 07의 상품에 대해 해당 상품을 가장 많이 구매한 상위 10명의 고객에 대한 판매율을 계산합니다. 각 행이 무엇을 하는지 그 내역을 설명합니다.
inner_join(df_receipt, df_product[c("product_cd", "category_major_cd")], by="product_cd"): df_receipt와 df_product의 데이터 프레임을 product_cd 열을 기준으로 결합합니다. cd 열을 기준으로 df_product의 product_cd와 category_major_cd 열만 유지한다. 그 결과, df_receipt에서 구매한 각 상품에 대한 카테고리 정보를 가진 새로운 데이터 프레임이 생성된다.
filter(category_major_cd == "07"): 1단계의 결합 데이터 프레임을 필터링하여 category_major_cd 컬럼이 "07"과 같은 행만 유지하도록 한다.
group_by(customer_id) %>% summarise(sum_07 = sum(amount), .groups = "drop"): 2단계에서 필터링된 데이터 프레임을 customer_id로 그룹화하여 각 그룹의 amount 컬럼의 합계를 계산한다. 그 결과, 각 고객이 카테고리 07의 제품에 지출한 금액의 합계를 가진 새로운 데이터 프레임을 얻을 수 있다.
inner_join(df_receipt, by="customer_id"): customer_id 열을 기준으로 3단계의 데이터 프레임과 원래의 df_receipt 데이터 프레임을 결합한다. 그 결과, 각 고객이 모든 상품에 대해 사용한 금액의 합계를 가진 새로운 데이터 프레임이 생성됩니다.
group_by(customer_id) %>% summarise(sum_all=sum(amount), sum_07=max(sum_07), .groups = "drop"): 이는 4단계에서 결합된 데이터 프레임을 customer_id로 그룹화 하고, 각 그룹의 amount 열의 합계와 각 그룹의 sum_07 열의 최대값을 계산하는 것입니다. 그 결과 각 고객이 전체 상품에 지출한 금액의 합계와 각 고객이 카테고리 07의 상품에 지출한 금액의 최대값을 가진 새로운 데이터 프레임이 만들어집니다.
mutate(sales_rate = sum_07 / sum_all): 카테고리 07 상품에 대한 최대 구매 금액(sum_07)을 전체 상품에 대한 총 금액(sum_all)으로 나누어 각 고객의 판매율을 계산하는 것입니다.
%>% slice(1:10) : 판매율 컬럼을 기준으로 데이터 프레임의 상위 10개 행만 유지합니다. 그 결과 카테고리 07 제품 판매율이 가장 높은 상위 10명의 고객과 전체 제품에 지출한 총 금액, 카테고리 07 제품에 지출한 최대 금액이 표시되는 새로운 데이터 프레임이 생성됩니다.
R-070: 영수증 내역 데이터(df_receipt)의 매출일(sales_ymd)에 대해 고객 데이터(df_customer)의 회원가입일(application_date)로부터의 경과일수를 계산하여 고객 ID(customer_id), 매출일, 회원가입일과 함께 10건을 표시하라(sales_ymd는 수치, application_date는 문자열로 데이터를 보관하고 있다는 점에 유의).
df_receipt[c("customer_id", "sales_ymd")] %>%
distinct(.,.keep_all=TRUE) %>% inner_join(df_customer[c("customer_id","application_date")], by="customer_id") %>% mutate(elapsed_days = as.integer( strptime(as.character(sales_ymd), "%Y%m%d") - strptime(application_date, "%Y%m%d"))) %>%
select(customer_id, sales_ymd, application_date, elapsed_days) %>%
slice(1:10)
customer_id | sales_ymd | application_date | elapsed_days |
---|---|---|---|
<chr> | <int> | <chr> | <int> |
CS006214000001 | 20181103 | 20150201 | 1371 |
CS008415000097 | 20181118 | 20150322 | 1337 |
CS028414000014 | 20170712 | 20150711 | 732 |
CS025415000050 | 20180821 | 20160131 | 933 |
CS003515000195 | 20190605 | 20150306 | 1552 |
CS024514000042 | 20181205 | 20151010 | 1152 |
CS040415000178 | 20190922 | 20150627 | 1548 |
CS027514000015 | 20191010 | 20151101 | 1439 |
CS025415000134 | 20190918 | 20150720 | 1521 |
CS021515000126 | 20171010 | 20150508 | 886 |
설명:
이 코드는 다음과 같은 작업을 수행합니다.
'df_receipt' 데이터 프레임에서 'customer_id'와 'sales_ymd' 컬럼을 선택합니다.
모든 컬럼을 유지한 채 중복된 행을 삭제한다('distinct').
완성된 데이터 프레임과 'df_customer' 데이터 프레임을 'customer_id'로 결합한다.
'elapsed_days' 컬럼을 새로 추가한다. 이는 'sales_ymd' 컬럼과 'application_date' 컬럼 사이의 일수 차이를 나타내며, 정수로 변환된다.
'customer_id', 'sales_ymd', 'application_date', 'elapsed_days' 컬럼만 선택한다.
결과 데이터 프레임의 처음 10줄을 반환한다.
코드의 내부 동작은 다음과 같은 단계로 나눌 수 있다.
# df_receipt에서 customer_id와 sales_ymd 컬럼 선택 df1 <- df_receipt[c("customer_id", "sales_ymd")] # 모든 컬럼을 유지한 채 중복된 행 삭제 df2 <- distinct(df1, . keep_all = TRUE) # 고객 ID로 df_customer와 결합 df3 <- inner_join(df2, df_customer[c("customer_id", "application_date")], by = "customer_id") # 경과일수 새 열 추가 df4 <- inner_join(df2, . 추가 df4 <- mutate(df3, elapsed_days = as. integer(strptime(as.character(sales_ymd), "%Y%m%d") - strptime(application_date, "%Y%m%d")))) # 열을 선택하고 처음 10행 반환 df5 <- select(df4, customer_id, sales_ymd, application_date, elapsed_days) slice(df5, 1:10)
이 코드에서는 dplyr 패키지를 사용하여 데이터 조작을 수행하는데, distinct 함수는 모든 열을 기준으로 중복된 행을 삭제하고, inner_join 함수는 공통된 열을 기준으로 두 데이터 프레임을 결합하고, mutate 함수는 데이터 프레임에 새로운 열을 생성하고, select 함수는 데이터 프레임에 새로운 열을 생성하고, select 함수는 데이터 프레임에서 특정 열을 선택한다. 마지막으로 slice 함수는 데이터 프레임에서 행의 하위 집합을 반환한다.
R-071: 영수증 내역 데이터(df_receipt)의 매출일(sales_ymd)에 대해 고객 데이터(df_customer)의 회원가입일(application_date)로부터의 경과 개월 수를 계산하여 고객 ID(customer_id), 매출일, 회원가입일과 함께 10건 표시 (sales_ymd는 숫자, application_date는 문자열로 데이터를 보관하는 점에 유의) 1개월 미만은 반올림한다.
df_receipt[c("customer_id", "sales_ymd")] %>%
distinct(., .keep_all = TRUE) %>%
inner_join(df_customer[c("customer_id", "application_date")], by = "customer_id") %>% mutate(elapsed_months = trunc(time_length( interval( strptime(application_date, "%Y%m%d"), strptime(as.character(sales_ymd), "%Y%m%d") ), "month"))) %>%
select(customer_id, sales_ymd, application_date, elapsed_months) %>%
slice(1:10)
customer_id | sales_ymd | application_date | elapsed_months |
---|---|---|---|
<chr> | <int> | <chr> | <dbl> |
CS006214000001 | 20181103 | 20150201 | 45 |
CS008415000097 | 20181118 | 20150322 | 43 |
CS028414000014 | 20170712 | 20150711 | 24 |
CS025415000050 | 20180821 | 20160131 | 30 |
CS003515000195 | 20190605 | 20150306 | 50 |
CS024514000042 | 20181205 | 20151010 | 37 |
CS040415000178 | 20190922 | 20150627 | 50 |
CS027514000015 | 20191010 | 20151101 | 47 |
CS025415000134 | 20190918 | 20150720 | 49 |
CS021515000126 | 20171010 | 20150508 | 29 |
설명:
이 코드는 다음과 같은 작업을 수행합니다.
df_receipt[c("customer_id", "sales_ymd")] df_receipt 데이터 프레임에서 customer_id와 sales_ymd 열만 선택합니다.
distinct(. , .keep_all = TRUE)는 모든 열을 유지한 채 중복된 행을 삭제한다. 이렇게 하면 customer_id와 sales_ymd의 고유한 조합에 대해 하나의 행만 존재하도록 보장합니다.
inner_join(df_customer[c("customer_id", "application_date")], by = "customer_id") 이전 단계의 결과와 df_customer 데이터 프레임을 customer_id 컬럼으로 결합하고 df_ customer에서 customer_id와 application_date 열만 선택한다.
mutate(elapsed_months = trunc(time_length( interval( strptime(application_date, "%Y%m%d"), strptime(as.character(sales_ymd), "%Y%m%d") ), " month")) application_date와 sales_ymd 사이의 개월 수를 계산하는 새로운 열 elapsed_months를 생성한다. strptime을 사용하여 날짜를 적절한 형식으로 변환하고, interval 함수를 사용하여 차이를 계산하고, time_length를 사용하여 개월 수를 계산하고, trunc 함수를 사용하여 가장 가까운 정수로 반올림합니다.
select(customer_id, sales_ymd, application_date, elapsed_months) customer_id, sales_ymd, application_date, elapsed_months 열만 선택한다.
slice(1:10)은 결과 데이터 프레임의 처음 10개의 행만 선택한다.
전체적으로 이 코드는 각 고객의 구매 내역을 기반으로 신청일과 판매일 사이의 개월 수를 계산한다.
R-072: 영수증 내역 데이터(df_receipt)의 매출일(df_customer)에 대해 고객 데이터(df_customer)의 회원가입 신청일(application_date)로부터의 경과년수를 계산하여 고객 ID(customer_id), 매출일, 회원가입 신청일과 함께 10건 (sales_ymd는 수치, application_date는 문자열로 데이터를 보관하고 있다는 점에 유의) 1년 미만은 반올림한다.
df_receipt[c("customer_id", "sales_ymd")] %>%
distinct(., .keep_all = TRUE) %>%
inner_join(df_customer[c("customer_id", "application_date")], by = "customer_id") %>% mutate(elapsed_years = trunc(time_length(interval( strptime(application_date, "%Y%m%d"), strptime(as.character(sales_ymd), "%Y%m%d")), "year")))%>%
select(customer_id, sales_ymd, application_date, elapsed_years) %>%
slice(1:10)
customer_id | sales_ymd | application_date | elapsed_years |
---|---|---|---|
<chr> | <int> | <chr> | <dbl> |
CS006214000001 | 20181103 | 20150201 | 3 |
CS008415000097 | 20181118 | 20150322 | 3 |
CS028414000014 | 20170712 | 20150711 | 2 |
CS025415000050 | 20180821 | 20160131 | 2 |
CS003515000195 | 20190605 | 20150306 | 4 |
CS024514000042 | 20181205 | 20151010 | 3 |
CS040415000178 | 20190922 | 20150627 | 4 |
CS027514000015 | 20191010 | 20151101 | 3 |
CS025415000134 | 20190918 | 20150720 | 4 |
CS021515000126 | 20171010 | 20150508 | 2 |
설명:
이 코드는 다음과 같은 처리를 수행한다.
df_receipt 데이터 프레임에서 customer_id와 sales_ymd 두 개의 열을 추출한다.
위 두 열의 중복된 행을 삭제하고 customer_id와 sales_ymd의 각 고유 쌍의 첫 번째 출현분만 유지한다.
얻은 데이터 프레임을 df_customer 데이터 프레임과 customer_id 컬럼으로 결합한다.
interval 함수로 구간을 만들고 time_length 함수로 연수를 추출하여 각 고객의 application_date와 sales_ymd 사이의 경과 연수를 계산하고, trunc 함수를 사용하여 결과를 정수 값으로 자른다.
customer_id, sales_ymd, application_date, elapsed_years 열을 선택한다.
마지막으로 slice 함수를 사용하여 결과 데이터 프레임의 처음 10개의 행을 선택합니다.
요약하면, 이 코드는 고객의 application_date와 sales_ymd 날짜 사이의 경과 년수를 계산하는 것이다.
R-073: 영수증 내역 데이터(df_receipt)의 매출일(sales_ymd)에 대해 고객 데이터(df_customer)의 회원가입일(application_date)로부터의 에포크 초 단위의 경과 시간을 계산하여 고객 ID(customer_id), 매출일, 회원가입일과 함께 10건을 표시한다. 과 함께 10건을 표시하라(단, sales_ymd는 수치, application_date는 문자열로 데이터를 보유하고 있다는 점에 유의). 단, 시간 정보는 보유하지 않으므로 각 날짜는 0시 0분 0초로 표시한다.
df_receipt[c("customer_id", "sales_ymd")] %>%
distinct(., .keep_all = TRUE) %>% inner_join(df_customer[c("customer_id","application_date")], by="customer_id") %>% mutate(elapsed_epoch = as.numeric(strptime(as.character(sales_ymd), "%Y%m%d")) - as.numeric(strptime(application_date, "%Y%m%d"))) %>%
select(customer_id, sales_ymd, application_date, elapsed_epoch) %>%
slice(1:10)
customer_id | sales_ymd | application_date | elapsed_epoch |
---|---|---|---|
<chr> | <int> | <chr> | <dbl> |
CS006214000001 | 20181103 | 20150201 | 118454400 |
CS008415000097 | 20181118 | 20150322 | 115516800 |
CS028414000014 | 20170712 | 20150711 | 63244800 |
CS025415000050 | 20180821 | 20160131 | 80611200 |
CS003515000195 | 20190605 | 20150306 | 134092800 |
CS024514000042 | 20181205 | 20151010 | 99532800 |
CS040415000178 | 20190922 | 20150627 | 133747200 |
CS027514000015 | 20191010 | 20151101 | 124329600 |
CS025415000134 | 20190918 | 20150720 | 131414400 |
CS021515000126 | 20171010 | 20150508 | 76550400 |
설명:
이 코드는 고객 및 구매 내역과 관련된 몇 가지 데이터를 처리하고 있습니다. 아래 코드를 한 줄씩 살펴보겠습니다.
df_receipt[c("customer_id", "sales_ymd")]: "df_receipt" 데이터 프레임에서 "customer_id"와 "sales_ymd" 열을 선택합니다.
distinct(. , .keep_all = TRUE): 모든 컬럼을 유지한 채 중복된 행을 삭제한다.
inner_join(df_customer[c("customer_id", "application_date")], by="customer_id"): "df_customer" 데이터 프레임에 "customer_id" 열을 사용하여 참여한다.
mutate(elapsed_epoch = as.numeric(strptime(as.character(sales_ymd), "%Y%m%d")) - as.numeric(strptime(application_date, "%Y%m%d")): "sales _ymd" 열과 "application_date" 열 사이의 초를 계산하는 "elapsed_epoch" 열을 새로 생성한다.
select(customer_id, sales_ymd, application_date, elapsed_epoch): 결합된 데이터 프레임에서 "customer_id", "sales_ymd", "application_date", "elapsed_epoch" 열을 선택합니다. epoch" 컬럼을 선택합니다.
slice(1:10): 결과 데이터 프레임에서 처음 10개의 행을 선택한다.
R-074: 영수증 내역 데이터(df_receipt)의 매출일(sales_ymd)에 대해 해당 주 월요일부터의 경과일수를 계산하여 매출일, 직전 월요일까지 10건씩 표시하라(sales_ymd는 수치로 데이터를 보관하고 있다는 점에 유의).
df_receipt["sales_ymd"] %>%
# 아래에서는 시작일이 일요일이기 때문에 하루 전으로 시프트하여 일요일을 전주 마지막 날로 변환하고 있다.
# 그 상태에서 floor_date를 하면 한 주의 시작일로 전주 일요일을 얻을 수 있기 때문이다,
# 시작일을 월요일로 만들기 위해 1을 더하고 있다.
mutate(monday = as.Date(floor_date( strptime(as.character(sales_ymd), "%Y%m%d") - 1 , unit = "week")) + 1) %>%
mutate(elapsed_days = as.integer( as.Date( strptime(as.character(sales_ymd), "%Y%m%d")) - monday)) %>%
select(sales_ymd, elapsed_days, monday) %>%
slice(1:10)
sales_ymd | elapsed_days | monday |
---|---|---|
<int> | <int> | <date> |
20181103 | 5 | 2018-10-29 |
20181118 | 6 | 2018-11-12 |
20170712 | 2 | 2017-07-10 |
20190205 | 1 | 2019-02-04 |
20180821 | 1 | 2018-08-20 |
20190605 | 2 | 2019-06-03 |
20181205 | 2 | 2018-12-03 |
20190922 | 6 | 2019-09-16 |
20170504 | 3 | 2017-05-01 |
20191010 | 3 | 2019-10-07 |
설명:
이 코드는 df_receipt 데이터 프레임의 각 판매일에 대해 주초(월요일)부터의 경과 일수를 계산합니다. 아래는 코드의 내용입니다.
df_receipt["sales_ymd"]: df_receipt 데이터 프레임에서 sales_ymd 컬럼을 선택한다.
%>%: 이전 작업의 결과를 다음 작업으로 전달하는 파이프 연산자이다.
mutate(monday = as.Date(floor_date( strptime(as.character(sales_ymd), "%Y%m%d") - 1 , unit = "week")) + 1): 각 판매일의 주 월요일을 나타내는 monday라는 새로운 컬럼을 생성한다. 라는 새로운 컬럼을 생성합니다. 이는 sales_ymd 컬럼을 날짜 객체로 변환하고, 이전 주에서 하루를 빼고(일요일이 주 끝), 하루를 더하여 주 시작(월요일)을 표시하는 방식으로 이루어진다.
%>%: 또 다른 파이프 연산자.
mutate(elapsed_days = as.integer( as.Date( strptime(as.character(sales_ymd), "%Y%m%d")) - Monday)): elapsed_days라는 새로운 컬럼을 생성하고, 각 판매일의 주 시작(월요일) 시작(월요일)부터 경과한 일수를 나타냅니다. 이는 sales_ymd 컬럼을 날짜 객체로 변환하고, (monday 컬럼에서) 해당 주의 월요일을 뺀 후 그 결과를 정수로 변환하는 방식으로 이루어진다.
%>%: 또 다른 파이프 연산자.
select(sales_ymd, elapsed_days, monday): sales_ymd, elapsed_days, monday 열을 선택한다.
%>%: 또 다른 파이프 연산자.
slice(1:10). 결과 데이터 프레임에서 처음 10개의 행을 선택합니다.
R-075: 고객 데이터(df_customer)에서 무작위로 1%의 데이터를 추출하여 맨 앞부터 10개를 표시하라.
head(sample_frac(tbl = df_customer, size = 0.01), 10)
customer_id | customer_name | gender_cd | gender | birth_day | age | postal_cd | address | application_store_cd | application_date | status_cd | |
---|---|---|---|---|---|---|---|---|---|---|---|
<chr> | <chr> | <chr> | <chr> | <date> | <int> | <chr> | <chr> | <chr> | <chr> | <chr> | |
1 | CS001612000311 | 岡本 美佳 | 1 | 女性 | 1951-03-21 | 68 | 211-0015 | 神奈川県川崎市中原区北谷町********** | S13001 | 20171118 | 0-00000000-0 |
2 | CS018415000209 | 西村 由美子 | 1 | 女性 | 1974-11-26 | 44 | 203-0051 | 東京都東久留米市小山********** | S13018 | 20151001 | C-20101026-D |
3 | CS020415000109 | 岡村 里奈 | 1 | 女性 | 1969-02-02 | 50 | 173-0001 | 東京都板橋区本町********** | S13020 | 20150207 | A-20100922-D |
4 | CS040403000046 | 辻 獅童 | 0 | 男性 | 1977-01-23 | 42 | 226-0016 | 神奈川県横浜市緑区霧が丘********** | S14040 | 20150813 | 0-00000000-0 |
5 | CS044313000008 | 河原 育子 | 1 | 女性 | 1985-06-03 | 33 | 144-0056 | 東京都大田区西六郷********** | S13044 | 20161204 | 0-00000000-0 |
6 | CS038502000025 | 小柳 ケンイチ | 0 | 男性 | 1963-06-01 | 55 | 134-0015 | 東京都江戸川区西瑞江********** | S13038 | 20151214 | 0-00000000-0 |
7 | CS034402000064 | 川越 明 | 0 | 男性 | 1972-11-27 | 46 | 213-0031 | 神奈川県川崎市高津区宇奈根********** | S14034 | 20170913 | 0-00000000-0 |
8 | CS015303000005 | 寺西 一徳 | 0 | 男性 | 1987-01-16 | 32 | 135-0016 | 東京都江東区東陽********** | S13015 | 20150223 | 0-00000000-0 |
9 | CS029411000007 | 森永 璃子 | 1 | 女性 | 1976-12-01 | 42 | 134-0085 | 東京都江戸川区南葛西********** | S12029 | 20150709 | 5-20101007-9 |
10 | CS048612000001 | 劇団 恵子 | 1 | 女性 | 1956-01-11 | 63 | 224-0053 | 神奈川県横浜市都筑区池辺町********** | S14048 | 20170920 | 0-00000000-0 |
설명:
이 코드는 dplyr 패키지의 sample_frac() 함수를 사용하여 df_customer 데이터 프레임에서 1%의 행을 무작위로 선택하고 head() 함수를 사용하여 결과 데이터 프레임의 처음 10개의 행을 반환합니다.
sample_frac() 함수는 데이터 프레임에서 일부 행을 무작위로 샘플링하는 데 사용됩니다. 이 경우 tbl 인수는 샘플링할 데이터 프레임을 지정하고, size 인수는 샘플링할 행의 비율(0.01, 즉 1%)을 지정한다. 결과 데이터 프레임은 head() 함수에 전달되어 처음 10개의 행을 반환한다.
R-076: 고객 데이터(df_customer)에서 성별 코드(gender_cd)의 비율에 따라 무작위로 10%의 데이터를 층화 추출하고, 성별 코드별로 건수를 집계하라.
set.seed(71) df_customer %>%
group_by(gender_cd) %>%
sample_frac(0.1) %>%
summarise(customer_num = n(), .groups = "drop")
gender_cd | customer_num |
---|---|
<chr> | <int> |
0 | 298 |
1 | 1792 |
9 | 107 |
설명:
이 코드는 dplyr 패키지를 사용하여 각 성별 그룹에서 고객의 10%를 무작위로 샘플링하고 각 샘플의 고객 수를 계산합니다.
set.seed(71)는 샘플링의 재현성을 보장하기 위해 난수 생성기의 종을 설정한다.
df_customer %>%는 df_customer 데이터 프레임을 입력으로 받아 파이프 연산자 %>%를 사용하여 다음 처리로 전달한다.
group_by(gender_cd) 성별 코드 열로 데이터를 그룹화합니다.
sample_frac(0.1)은 각 성별 그룹에서 고객의 10%를 샘플링하며, sample_frac() 함수는 그룹화된 데이터 프레임에서 행의 일부를 무작위로 샘플링하는 데 사용됩니다. 인수 0.1은 샘플링할 비율을 지정한다.
summarise(customer_num = n(), .groups = "drop")은 각 성별 그룹의 고객 수를 계산한다. n() 함수는 각 그룹의 행 수를 계산하고 결과 열의 이름을 customer_num으로 변경한다. .groups 인수를 "drop"으로 설정하면 출력에서 그룹화 정보가 삭제된다.
최종 출력은 gender_cd와 customer_num 두 개의 열이 있는 데이터 프레임으로, gender_cd 열은 성별 코드를 지정하고 customer_num 열은 각 성별 그룹에서 샘플링된 고객 수를 지정한다.
R-077: 영수증 명세서 데이터(df_receipt)의 매출 금액을 고객 단위로 합산하고, 합산한 매출 금액의 편차를 추출하라. 단, 이상값은 매출금액 합계를 로그화한 후 평균과 표준편차를 계산하여 그 평균에서 3σ 이상 벗어난 것으로 한다(자연대수, 상용대수 모두 가능). 결과는 10건 표시하라.
df_receipt %>%
group_by(customer_id) %>%
summarise(sum_amount = sum(amount), .groups = "drop") %>%
mutate(log_sum_amount = log(sum_amount + 0.5)) %>%
filter(abs(log_sum_amount - mean(log_sum_amount)) / sd(log_sum_amount) > 3) %>% slice(1:10)
customer_id | sum_amount | log_sum_amount |
---|---|---|
<chr> | <int> | <dbl> |
ZZ000000000000 | 12395003 | 16.3328 |
설명:
이 코드는 df_receipt라는 데이터 프레임을 처리하며 다음과 같은 작업을 수행한다.
group_by 함수를 사용하여 customer_id로 데이터 프레임을 그룹화한다.
summarise 함수를 사용하여 각 고객의 금액 합계를 계산하여 sum_amount라는 새로운 컬럼에 저장한다.
sum_amount 열의 대수를 취하여 log_sum_amount라는 새로운 열에 저장한다.
각 값에서 log_sum_amount의 평균값을 빼고 그 결과를 log_sum_amount의 표준편차로 나누어 log_sum_amount의 z-score를 계산한다.
log_sum_amount의 z-score가 3보다 큰 고객(즉, log_sum_amount가 평균값에서 표준편차로 3 이상 떨어져 있는 고객)을 필터링한다.
slice 함수를 사용하여 결과 데이터 프레임의 처음 10 줄을 선택한다.
요약하면, 이 코드는 Z점수를 계산하고 Z점수가 특정 임계치를 초과하는 고객을 필터링하여 총 지출액이 평균보다 훨씬 높거나 낮은 고객을 식별한다.
R-078: 영수증 내역 데이터(df_receipt)의 매출 금액(amount)을 고객 단위로 합산하고, 합산된 매출 금액의 외곽값을 추출한다. 단, 고객 ID가 “Z”로 시작하는 것은 비회원을 의미하므로 제외하여 계산한다. 여기서 이상값은 1사분위와 3사분위의 차이인 IQR을 이용하여 ‘1사분위수 -1.5×IQR’ 이하 또는 ‘3사분위수+1.5×IQR’을 초과하는 것으로 한다. 결과는 10건 표시한다.
df_receipt %>%
group_by(customer_id) %>%
filter(!grepl("^Z", customer_id)) %>%
summarise(sum_amount = sum(amount), .groups = "drop") %>%
filter( sum_amount < quantile(sum_amount)[2] - 1.5 * (quantile(sum_amount)[4] - quantile(sum_amount)[2]) | sum_amount > quantile(sum_amount)[4] + 1.5 * (quantile(sum_amount)[4] - quantile(sum_amount)[2]) ) %>%
slice(1:10)
customer_id | sum_amount |
---|---|
<chr> | <int> |
CS001414000048 | 8584 |
CS001605000009 | 18925 |
CS002415000594 | 9568 |
CS004414000181 | 9584 |
CS005415000137 | 8734 |
CS006414000001 | 9156 |
CS006414000029 | 9179 |
CS006415000105 | 10042 |
CS006415000147 | 12723 |
CS006415000157 | 10648 |
설명:
본 코드는 다음과 같은 처리를 한다.
df_receipt 데이터 프레임을 customer_id로 그룹화한다.
customer_id가 "Z"로 시작하는 모든 행을 필터링한다.
각 customer_id의 금액을 합산한다.
사분위수 범위(IQR) 방법을 사용하여 sum_amount 값의 상위와 하위 1.5%를 필터링한다.
완성된 데이터 프레임의 첫 10개의 행을 선택한다.
IQR 방법은 사분위수를 기준으로 데이터 세트에서 이상값을 감지하고 제거하는 방법이다. 이 경우, 상한과 하한은 다음과 같이 계산된다.
상계: quantile(sum_amount)[4] + 1.5 * (quantile(sum_amount)[4] - quantile(sum_amount)[2])
하한 : quantile(sum_amount)[2] - 1.5 * (quantile(sum_amount)[4] - quantile(sum_amount)[2])
이 범위를 벗어나는 sum_amount 값은 필터링된다. 결과 데이터 프레임에는 필터 조건을 만족하는 처음 10개의 고객_id와 sum_amount가 포함된다.
R-079: 상품 데이터(df_product)의 각 항목에 대해 결손 수를 확인하라.
sapply(df_product, function(x) sum(is.na(x)))
product_cd
0
category_major_cd
0
category_medium_cd
0
category_small_cd
0
unit_price
7
unit_cost
7
설명:
이 코드는 sapply() 함수를 사용하여 df_product 데이터 프레임의 각 열의 결손값 수를 계산한다.
sapply()는 df_product 데이터 프레임의 각 열에 함수를 적용한다. 여기서 사용되는 함수는 function(x) sum(is.na(x))로 입력 열 x의 결손값(NA) 수를 계산한다. is.na()는 입력 벡터와 같은 길이의 논리 벡터를 반환하고, 결손값(NA)이 있으면 TRUE, 없으면 FALSE를 반환하고, sum()은 논리 벡터의 TRUE 값을 합산하여 열에서 누락된 값의 개수를 제공한다.
이 코드의 출력은 df_product의 열 이름을 이름으로, 해당 결손값의 개수를 값으로 하는 명명된 벡터이다.
R-080: 상품 데이터(df_product) 중 어느 한 항목에 결손이 발생한 레코드를 모두 삭제한 새로운 상품 데이터를 생성한다. 또한, 삭제 전후의 건수를 표시하고, 079에서 확인한 건수만큼 감소한 것도 확인해야 한다.
df_product_1 <- na.omit(df_product) paste("削除前:", nrow(df_product)) paste("削除後:", nrow(df_product_1))
'삭제전: 10030'
'삭제후: 10023'
설명:
첫 번째 코드에서는 na.omit() 함수를 사용하여 원래 데이터 프레임 df_product에서 결손값(NA)이 있는 모든 행을 제거한 새로운 데이터 프레임 df_product_1을 생성하고 있다.
두 번째 코드에서는 paste() 함수를 사용하여 NA를 제거하기 전과 제거한 후의 df_product의 행 수를 나타내는 메시지를 표시하고 있습니다. 구체적으로 nrow(df_product)는 df_product의 행 수를 반환하고, 첫 번째 paste() 호출은 이 숫자와 '삭제 전:' 문자열을 연결하고 있습니다. 마찬가지로 nrow(df_product_1)는 새로운 데이터 프레임 df_product_1의 행 수를 반환하고, 두 번째 paste() 호출은 이 숫자와 "After deletion:"이라는 문자열을 연결한다.
이 코드는 데이터 프레임의 관측치 수에 대한 NA 삭제 효과를 빠르게 확인할 수 있는 방법을 제공한다.
Comment