データサイエンス100本ノック(構造化データ加工編)- R Part 4 (Q61 to Q80)

データサイエンス
解説:

このコードは、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データフレームに各顧客が使った合計金額の対数を持つ新しい列を作成し、これは歪んだデータを正規化するためによく使われる変換です。
 
解説:

このコードは、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行を選択する。
 
解説:

このコードはデータフレームdf_productを受け取り、mutate()関数を使用して新しい列unit_profitを作成します。unit_profit列は、df_productの既存の列であるunit_priceとunit_costの差として計算されています。

そして、slice()関数を使用して、新しいunit_profitカラムを含む結果のデータフレームの最初の10行を表示します。
 
解説:

このコードは、df_productという名前のデータフレームに対していくつかの計算を実行しています。

mutateはunit_profit_rateという新しい列を作成するために使用されています。この列は、単価から単価を引き、その結果を単価で割ることによって計算されます。

次にsummarise関数を使用してunit_profit_rate列の平均を計算します。その結果はtotal_meanという新しい列に代入されます。

要約すると、このコードはdf_productで販売された製品の各ユニットの平均利益率を計算していることになります。
 
解説:

このコードは、以下のステップを実行します。

データフレーム "df_product "から "product_cd"、"unit_price"、"unit_cost "の列のみを選択する。

単価を0.7で割り、その結果を最も近い整数に切り捨てることにより、「new_price」という新しい列を作成する。これは、商品の価格を一定の割合で下げるための任意の計算である。

新しい価格から単価を引き、その結果を新しい価格で割ることによって、「new_profit_rate」という別の新しい列を作成します。これは、新価格の利益率を計算するためのものです。

最後に、出来上がったデータフレームから最初の10行を選択します。
 
解説:

このコードは、商品データ・フレーム(df_product)に対していくつかの計算を実行しています。

まず、"product_cd"、"unit_price"、"unit_cost "の3つのカラムを選択しています。

これは、"unit_cost "を0.7で割り(つまり、コストを30%削減)、その結果をround()関数を使って最も近い整数に丸めることによって算出されます。

次に、新しい列「new_profit_rate」を作成します。これは、「new_price」から「unit_cost」を引き、その結果を「new_price」で割ることで算出します。

最後に、出来上がったデータフレームの最初の10行を選択し、表示します。

このコードは、基本的に、生産コストを30%削減した場合の各製品の新しい価格と利益率を計算します。
 
解説:

このコードは、2つの新しい変数 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行を表示するために使用されます。
 
解説:

このコードでは、cbind関数を使用して、df_productデータフレームの3つの列、すなわちproduct_cd、unit_price、tax_priceを新しいデータフレームに結合しています。次にhead関数を用いて、この新しいデータフレームの最初の10行を表示する。

新しいデータフレームの最初の列はproduct_cdと表示され、df_productのproduct_cd列の値が含まれています。2列目はdf_product$unit_priceというラベルで、df_productのunit_price列の値が格納されています。

3番目の列はtax_priceというラベルで、unit_price列の各値に1.1を掛けた結果にtrunc関数を適用して作成されています。これは、10%の税金を含む製品の価格を計算するものです。

cbind関数がすでにdf_productからunit_price列を抽出しているので、2列目の列名にdf_product$を使用する必要はないことに注意してください。
 
解説:
# コード例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関数は、データフレームから行のサブセットを抽出するために使用されます。

 

解説:

このコードは、カテゴリー07の商品について、その商品を最も多く購入した上位10名の顧客に対する販売率を計算しています。各行が何を行っているのか、その内訳を説明します。

inner_join(df_receipt, df_product[c("product_cd", "category_major_cd")], by="product_cd"): これは、df_receiptとdf_productのデータフレームをproduct_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製品に費やした最大金額が表示された新しいデータフレームになります。
 
解説:

このコードは、以下のタスクを実行します。

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 <- 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関数は、共通の列に基づいて2つのデータフレームを結合しています。mutate関数はデータフレームに新しい列を作成し、select関数はデータフレームから特定の列を選択する。最後に、slice 関数は、データフレームから行のサブセットを返します。
 
解説:

このコードでは、以下の処理を行います。

df_receipt[c("customer_id", "sales_ymd")] df_receipt データフレームから customer_id と sales_ymd の列のみを選択します。

distinct(., .keep_all = TRUE) は、すべての列を保持したまま、重複する行を削除します。これにより、customer_idとsales_ymdのユニークな組み合わせに対して1行しか存在しないことが保証されます。

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行のみを選択します。

全体として、このコードは、各顧客の購入履歴に基づいて、申込日と販売日の間の月数を計算しています。
 
解説:

このコードは、以下の処理を実行します。

df_receiptデータフレームからcustomer_idとsales_ymdの2つのカラムを抽出する。

上記2列の重複行を削除し、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の日付の間の経過年数を計算するものです。
 
解説:

このコードは、顧客とその購入履歴に関連するいくつかのデータを処理しています。以下、コードを一行ずつ解説していきます。

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" カラムを選択します。

slice(1:10): 結果のデータフレームから最初の10行を選択する。

 

解説:

このコードは、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 = "週")) + 1): これは、各売上日の週の月曜日を表す monday という新しいカラムを作成します。これは、sales_ymdカラムを日付オブジェクトに変換し、1日引いて前週に切り捨て(日曜日が週の終わり)、1日足して週の始まり(月曜日)とすることで実現します。

%>%: もうひとつのパイプ演算子。

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行を選択します。

 

解説:

このコードは、dplyr パッケージの sample_frac() 関数を使用して、df_customer データフレーム内の行の 1% をランダムに選択し、head() 関数を使用して結果のデータフレームの最初の 10 行を返します。

sample_frac() 関数は、データフレームから一部の行をランダムにサンプリングするために使用されます。この場合、tbl引数はサンプリングするデータフレームを指定し、size引数はサンプリングする行の割合(0.01、つまり1%)を指定します。結果のデータフレームはhead()関数に渡され、最初の10行を返します。
 
 
解説:

このコードは、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 の2つのカラムを持つデータフレームになります。gender_cd列は性別コードを指定し、customer_num列は各性別グループからサンプリングされた顧客の数を指定する。
 
解説:

このコードは、df_receiptというデータフレームを処理し、以下のことを行っています。

group_by関数を使用して、データフレームをcustomer_idでグループ化する。

summarise関数を使用して各顧客の金額の合計を計算し、sum_amountという新しいカラムに格納する。

sum_amount列の対数をとり、log_sum_amountという新しい列に格納する。

各値からlog_sum_amountの平均値を引き、その結果をlog_sum_amountの標準偏差で割って、log_sum_amountのzスコアを計算する。

log_sum_amountのzスコアが3より大きい顧客(すなわち、log_sum_amountが平均値から標準偏差で3以上離れている顧客)をフィルタリングする。

slice関数を使用して、結果のデータフレームの最初の10行を選択する。

要約すると、このコードは、Zスコアを計算し、Zスコアがある閾値を超える顧客をフィルタリングすることで、総支出額が平均より大幅に高いか低い顧客を特定しています。

 

解説:

本コードは、以下の処理を行う。

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行のcustomer_idとsum_amountが含まれます。
 
解説:

このコードは、sapply()関数を使用して、df_product データフレームの各列における欠損値の数を計算する。

sapply()は、df_productのデータフレームの各列に関数を適用します。ここで、使用される関数は function(x) sum(is.na(x)) で、入力列 x の欠損値 (NA) の数を計算します。is.na() は、入力ベクトルと同じ長さで、欠損値 (NA) があれば TRUE、なければ FALSE の論理ベクトルを返し、sum() は論理ベクトルの TRUE 値を合計し、列中の欠損値のカウントを与えます。

このコードの出力は、df_productの列名を名前として、それに対応する欠損値のカウントを値として持つ名前付きベクトルです。
 
解説:

1行目のコードでは、na.omit()関数を使って、元のデータフレームdf_productから欠損値(NA)を持つすべての行を削除した新しいデータフレームdf_product_1を作成しています。

2行目のコードでは、paste()関数を使用して、NAの除去前と除去後のdf_productの行数を示すメッセージを表示しています。具体的には、nrow(df_product)はdf_productの行数を返し、最初のpaste()呼び出しはこの数と文字列「削除前:」を連結しています。同様に、nrow(df_product_1)は新しいデータフレームdf_product_1の行数を返し、2番目のpaste()呼び出しはこの数を "After deletion: "という文字列と連結させる。

このコードは、データフレーム内のオブザベーションの数に対するNAの削除の効果をチェックする迅速な方法を提供します。
 
 
 
 

Comment