python, R, vimでデータマイニング

python, R, vim で疑問に思ったことなどを

欠損値置換や因子ベクトル化をmutate_eachで

 Rでのデータ加工がいつも捗らなくて困っていた。
dplyrをより活用することでもっと効率的にしたい。
そのなかでもmutate_eachは使う場面が多そうなので慣れておきたい。

全変数を因子ベクトル化

 例えば、カテゴリ型の変数名を指名して対象変数を因子ベクトルにしたいことは多い。
自作のコードが煩雑になり困っていた。
そこでdplyr:mutate_eachを使用してみる。
irisの全変数をfactorで因子ベクトル化する。

それから関数はmutate_eachとmutate_each_がある。 (違いは他を当たってください)

library(dplyr)
## 
## Attaching package: 'dplyr'
## 
##  以下のオブジェクトは 'package:stats' からマスクされています: 
## 
##      filter, lag 
## 
##  以下のオブジェクトは 'package:base' からマスクされています: 
## 
##      intersect, setdiff, setequal, union
packageVersion("dplyr")
## [1] '0.4.3'
iris <- tbl_df(iris)
iris.factor <- mutate_each(iris, funs(factor))
str(iris.factor)
## Classes 'tbl_df', 'tbl' and 'data.frame':    150 obs. of  5 variables:
##  $ Sepal.Length: Factor w/ 35 levels "4.3","4.4","4.5",..: 9 7 5 4 8 12 4 8 2 7 ...
##  $ Sepal.Width : Factor w/ 23 levels "2","2.2","2.3",..: 15 10 12 11 16 19 14 14 9 11 ...
##  $ Petal.Length: Factor w/ 43 levels "1","1.1","1.2",..: 5 5 4 6 5 8 5 6 5 6 ...
##  $ Petal.Width : Factor w/ 22 levels "0.1","0.2","0.3",..: 2 2 2 2 2 4 3 2 2 1 ...
##  $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...

変数を指定する。

 変数名はlistなどで指定できる。その他にも便利な指定方法があるようなので他を当たってみてください。

iris.factor2 <- mutate_each_(iris, funs(factor), list("Sepal.Length", "Species"))
str(iris.factor2)
## Classes 'tbl_df', 'tbl' and 'data.frame':    150 obs. of  5 variables:
##  $ Sepal.Length: Factor w/ 35 levels "4.3","4.4","4.5",..: 9 7 5 4 8 12 4 8 2 7 ...
##  $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
##  $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
##  $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
##  $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
iris.factor2 <- mutate_each(iris, funs(factor), Species)
iris.factor2 <- mutate_each_(iris, funs(factor), list(quote(Species), quote(Sepal.Length)))
iris.factor2 <- mutate_each(iris, funs(factor), -Species)
iris.factor2 <- mutate_each_(iris, funs(factor), "-Sepal.Length")

新規追加する変数名

 一つ困っていることがある。
funsで関数名を指定する。指定した関数がひとつの場合は元の変数を上書きする。
指定した関数が2つ以上の場合は元の変数を上書きせず、関数名をsuffixとした新規変数を作成する。
適用したい関数がひとつの場合でも元の変数を残したいのだがその方法がわからない。

str(mutate_each_(iris, funs(half = ./2), list("Sepal.Length", "Sepal.Width")))
## Classes 'tbl_df', 'tbl' and 'data.frame':    150 obs. of  5 variables:
##  $ Sepal.Length: num  2.55 2.45 2.35 2.3 2.5 2.7 2.3 2.5 2.2 2.45 ...
##  $ Sepal.Width : num  1.75 1.5 1.6 1.55 1.8 1.95 1.7 1.7 1.45 1.55 ...
##  $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
##  $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
##  $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
str(mutate_each_(iris, funs(half = ./2, log), list("Sepal.Length", "Sepal.Width")))
## Classes 'tbl_df', 'tbl' and 'data.frame':    150 obs. of  9 variables:
##  $ Sepal.Length     : num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
##  $ Sepal.Width      : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
##  $ Petal.Length     : num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
##  $ Petal.Width      : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
##  $ Species          : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
##  $ Sepal.Length_half: num  2.55 2.45 2.35 2.3 2.5 2.7 2.3 2.5 2.2 2.45 ...
##  $ Sepal.Width_half : num  1.75 1.5 1.6 1.55 1.8 1.95 1.7 1.7 1.45 1.55 ...
##  $ Sepal.Length_log : num  1.63 1.59 1.55 1.53 1.61 ...
##  $ Sepal.Width_log  : num  1.25 1.1 1.16 1.13 1.28 ...