web-dev-qa-db-ja.com

dplyrのmutate_each / summarise_each:特定の列を選択し、変更された列に新しい名前を付けるにはどうすればよいですか?

dplyr動詞mutate_each.について少し混乱しています

基本的なmutateを使用してデータの列をたとえばZスコアに変換し、data.frameに新しい列を作成するのは非常に簡単です(ここではz_score_dataという名前):

newDF <- DF %>%
  select(one_column) %>%
  mutate(z_score_data = one_column - (mean(one_column) / sd(one_column))

ただし、変換するデータの列が多数あるため、mutate_each動詞を使用する必要があるようです。

newDF <- DF %>%
     mutate_each(funs(scale))

ここまでは順調ですね。しかし、まだ私は理解することができませんでした:

  1. mutateでできるように、これらの新しい列に適切な名前を付けるにはどうすればよいですか?
  2. 最初のケースでselectで行ったように、変更したい特定の列を選択するにはどうすればよいですか?

ご協力いただきありがとうございます。

59
Matt O'Brien

Dplyr> = 0.4.3.9000の更新

Dplyr開発バージョン0.4.3.9000(執筆時点)では、mutate_eachおよびsummarise_each内の名前付けが News に記載されているように簡素化されました。

summarise_each()mutate_each()の命名動作が調整されたため、関数と変数名の両方を強制的に含めることができます:summarise_each(mtcars, funs(mean = mean), everything())

mutate_each/summarise_each内で1つの関数のみを適用し、それらの列に新しい名前を付けたい場合、これは主に重要です。

違いを示すために、以下のオプションa.2とは対照的に、新しい命名機能を使用したdplyr 0.4.3.9000からの出力を示します。

library(dplyr) # >= 0.4.3.9000
iris %>% mutate_each(funs(mysum = sum(.)), -Species) %>% head()
#  Sepal.Length Sepal.Width Petal.Length Petal.Width Species Sepal.Length_mysum Sepal.Width_mysum
#1          5.1         3.5          1.4         0.2  setosa              876.5             458.6
#2          4.9         3.0          1.4         0.2  setosa              876.5             458.6
#3          4.7         3.2          1.3         0.2  setosa              876.5             458.6
#4          4.6         3.1          1.5         0.2  setosa              876.5             458.6
#5          5.0         3.6          1.4         0.2  setosa              876.5             458.6
#6          5.4         3.9          1.7         0.4  setosa              876.5             458.6
#  Petal.Length_mysum Petal.Width_mysum
#1              563.7             179.9
#2              563.7             179.9
#3              563.7             179.9
#4              563.7             179.9
#5              563.7             179.9
#6              563.7             179.9

新しい名前を指定せず、1つの関数のみを指定すると、dplyrは既存の列を変更します(以前のバージョンと同様)。

iris %>% mutate_each(funs(sum), -Species) %>% head()
#  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#1        876.5       458.6        563.7       179.9  setosa
#2        876.5       458.6        563.7       179.9  setosa
#3        876.5       458.6        563.7       179.9  setosa
#4        876.5       458.6        563.7       179.9  setosa
#5        876.5       458.6        563.7       179.9  setosa
#6        876.5       458.6        563.7       179.9  setosa

この新しい機能は、次のリリースバージョン0.4.4でCRANを介して利用できると想定しています。


dplyrバージョン<= 0.4.3:

これらの新しい列に適切な名前を付けるにはどうすればよいのでしょうか?

a)mutate_each/summarise_eachに適用される1つの関数

mutate_eachまたはsummarise_each内に1つの関数のみを適用する場合、既存の列は変換され、名前は以前の状態のままになります。名前付きベクトルをmutate_each_/summarise_each_に指定しない限り.4)

ここではいくつかの例を示します。

a.1のみ1つの関数->既存の名前を保持します

iris %>% mutate_each(funs(sum), -Species) %>% head()
#  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#1          876         459          564         180  setosa
#2          876         459          564         180  setosa
#3          876         459          564         180  setosa
#4          876         459          564         180  setosa
#5          876         459          564         180  setosa
#6          876         459          564         180  setosa

a.2また、新しい列名拡張子を指定する場合:

iris %>% mutate_each(funs(mysum = sum(.)), -Species) %>% head()
#  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#1          876         459          564         180  setosa
#2          876         459          564         180  setosa
#3          876         459          564         180  setosa
#4          876         459          564         180  setosa
#5          876         459          564         180  setosa
#6          876         459          564         180  setosa

a.3列ごとに新しい名前を手動で指定します(ただし、いくつかの列でのみ実用的です)。

iris %>% mutate_each(funs(sum), SLsum = Sepal.Length,SWsum = Sepal.Width,  -Species) %>% head()
#  Sepal.Length Sepal.Width Petal.Length Petal.Width Species SLsum SWsum
#1          5.1         3.5          1.4         0.2  setosa   876   459
#2          4.9         3.0          1.4         0.2  setosa   876   459
#3          4.7         3.2          1.3         0.2  setosa   876   459
#4          4.6         3.1          1.5         0.2  setosa   876   459
#5          5.0         3.6          1.4         0.2  setosa   876   459
#6          5.4         3.9          1.7         0.4  setosa   876   459

a.4名前付きベクトルを使用して、新しい名前で追加の列を作成します。

ケース1:元の列を保持する

オプションa.1、a.2、a.3とは異なり、dplyrは既存の列を変更せずに保持し、このアプローチで新しい列を作成します。新しい列の名前は、事前に作成する名前付きベクトルの名前と同じです(この場合はvars)。

vars <- names(iris)[1:2]  # choose which columns should be mutated
vars <- setNames(vars, paste0(vars, "_sum")) # create new column names
iris %>% mutate_each_(funs(sum), vars) %>% head 
#  Sepal.Length Sepal.Width Petal.Length Petal.Width Species Sepal.Length_sum Sepal.Width_sum
#1          5.1         3.5          1.4         0.2  setosa            876.5           458.6
#2          4.9         3.0          1.4         0.2  setosa            876.5           458.6
#3          4.7         3.2          1.3         0.2  setosa            876.5           458.6
#4          4.6         3.1          1.5         0.2  setosa            876.5           458.6
#5          5.0         3.6          1.4         0.2  setosa            876.5           458.6
#6          5.4         3.9          1.7         0.4  setosa            876.5           458.6

ケース2:元の列を削除する

ご覧のとおり、このアプローチは既存の列を変更せずに保持し、指定された名前の新しい列を追加します。元の列を保持したくないが、新しく作成した列(および他の列)だけを保持したい場合は、後でselectステートメントを追加するだけです。

iris %>% mutate_each_(funs(sum), vars) %>% select(-one_of(vars)) %>% head
#  Petal.Length Petal.Width Species Sepal.Length_sum Sepal.Width_sum
#1          1.4         0.2  setosa            876.5           458.6
#2          1.4         0.2  setosa            876.5           458.6
#3          1.3         0.2  setosa            876.5           458.6
#4          1.5         0.2  setosa            876.5           458.6
#5          1.4         0.2  setosa            876.5           458.6
#6          1.7         0.4  setosa            876.5           458.6

b)mutate_each/summarise_eachで適用される複数の関数

b.1 dplyrに新しい名前を理解させる

複数の関数を適用した場合、dplyrに名前を自動的に認識させることができます(既存の列は保持されます)。

iris %>% mutate_each(funs(sum, mean), -Species) %>% head()
#  Sepal.Length Sepal.Width Petal.Length Petal.Width Species Sepal.Length_sum Sepal.Width_sum Petal.Length_sum
#1          5.1         3.5          1.4         0.2  setosa              876             459              564
#2          4.9         3.0          1.4         0.2  setosa              876             459              564
#3          4.7         3.2          1.3         0.2  setosa              876             459              564
#4          4.6         3.1          1.5         0.2  setosa              876             459              564
#5          5.0         3.6          1.4         0.2  setosa              876             459              564
#6          5.4         3.9          1.7         0.4  setosa              876             459              564
#  Petal.Width_sum Sepal.Length_mean Sepal.Width_mean Petal.Length_mean Petal.Width_mean
#1             180              5.84             3.06              3.76              1.2
#2             180              5.84             3.06              3.76              1.2
#3             180              5.84             3.06              3.76              1.2
#4             180              5.84             3.06              3.76              1.2
#5             180              5.84             3.06              3.76              1.2
#6             180              5.84             3.06              3.76              1.2

b.2新しい列名を手動で指定する

別のオプションは、複数の関数を使用する場合、独自に列名の拡張子を指定することです。

iris %>% mutate_each(funs(MySum = sum(.), MyMean = mean(.)), -Species) %>% head()
#  Sepal.Length Sepal.Width Petal.Length Petal.Width Species Sepal.Length_MySum Sepal.Width_MySum Petal.Length_MySum
#1          5.1         3.5          1.4         0.2  setosa                876               459                564
#2          4.9         3.0          1.4         0.2  setosa                876               459                564
#3          4.7         3.2          1.3         0.2  setosa                876               459                564
#4          4.6         3.1          1.5         0.2  setosa                876               459                564
#5          5.0         3.6          1.4         0.2  setosa                876               459                564
#6          5.4         3.9          1.7         0.4  setosa                876               459                564
#  Petal.Width_MySum Sepal.Length_MyMean Sepal.Width_MyMean Petal.Length_MyMean Petal.Width_MyMean
#1               180                5.84               3.06                3.76                1.2
#2               180                5.84               3.06                3.76                1.2
#3               180                5.84               3.06                3.76                1.2
#4               180                5.84               3.06                3.76                1.2
#5               180                5.84               3.06                3.76                1.2
#6               180                5.84               3.06                3.76                1.2

最初のケースで選択したように、変更したい特定の列を選択するにはどうすればよいですか?

これを行うには、名前を次のように指定して(変更されたSepal.Lengthを変更しますが、Speciesではありません)、変更する(または除外する)列を参照します。

iris %>% mutate_each(funs(sum), Sepal.Length, -Species) %>% head()

さらに、特別な関数を使用して、たとえば、特定のWordなどで始まるまたは含むすべての列を変更する列を選択できます。例:

iris %>% mutate_each(funs(sum), contains("Sepal"),  -Species) %>% head()

これらの関数の詳細については、?mutate_eachおよび?selectを参照してください。

コメントの後に編集1:

標準評価を使用する場合、dplyrは、追加の「_」で終わるほとんどの関数のSEバージョンを提供します。したがって、この場合は次を使用します。

x <- c("Sepal.Width", "Sepal.Length") # vector of column names 
iris %>% mutate_each_(funs(sum), x) %>% head()

ここで使用したmutate_each_に注目してください。


編集2:オプションa.4で更新

103

mutate_eachは廃止予定です。mutate_atの使用を検討してください。 dplyr_0.5.0ドキュメントから:

将来的には、mutate_each()およびsummarise_each()は廃止され、より特徴のある関数ファミリーになります:mutate_all()、mutate_at()、mutate_if()、summarise_all()、summarise_at()およびsummarise_if()。

Speciesを除くすべての変数に関数を適用します。

警告: '.cols'パラメータは非推奨です。下部の注意を参照してください!

iris %>% mutate_at(.cols=vars(-Species), .funs=funs(mysum = sum(.))) %>% head()

 Sepal.Length Sepal.Width Petal.Length Petal.Width Species Sepal.Length_mysum Sepal.Width_mysum
1          5.1         3.5          1.4         0.2  setosa              876.5             458.6
2          4.9         3.0          1.4         0.2  setosa              876.5             458.6
3          4.7         3.2          1.3         0.2  setosa              876.5             458.6
4          4.6         3.1          1.5         0.2  setosa              876.5             458.6
5          5.0         3.6          1.4         0.2  setosa              876.5             458.6
6          5.4         3.9          1.7         0.4  setosa              876.5             458.6
  Petal.Length_mysum Petal.Width_mysum
1              563.7             179.9
2              563.7             179.9
3              563.7             179.9
4              563.7             179.9
5              563.7             179.9
6              563.7             179.9

変数のサブセットに関数を適用します

vars_to_process=c("Petal.Length","Petal.Width")
iris %>% mutate_at(.cols=vars_to_process, .funs=funs(mysum = sum(.))) %>% head()

 Sepal.Length Sepal.Width Petal.Length Petal.Width Species Petal.Length_mysum Petal.Width_mysum
1          5.1         3.5          1.4         0.2  setosa              563.7             179.9
2          4.9         3.0          1.4         0.2  setosa              563.7             179.9
3          4.7         3.2          1.3         0.2  setosa              563.7             179.9
4          4.6         3.1          1.5         0.2  setosa              563.7             179.9
5          5.0         3.6          1.4         0.2  setosa              563.7             179.9
6          5.4         3.9          1.7         0.4  setosa              563.7             179.9

更新! dplyr 0.7.1バージョン(2017-08-08)

メッセージが表示される場合:

.colsは名前が変更されて廃止されました。.varsを使用してください

.cols.varsを変更します。

iris %>% mutate_at(.vars=vars(-Species), .funs=funs(mysum = sum(.))) %>% head()

もう一つの例:

iris %>% mutate_at(.vars=vars(Sepal.Width), .funs=funs(mysum = sum(.))) %>% head()

以下と同等です:

iris %>% mutate_at(.vars=vars("Sepal.Width"), .funs=funs(mysum = sum(.))) %>% head()

また、このバージョンではmutate_eachは非推奨です:

mutate_each()は非推奨です。代わりにmutate_all()mutate_at()、またはmutate_if()を使用してください。 funsを選択した変数にマッピングするには、mutate_at()を使用します

13
pablo_sci