web-dev-qa-db-ja.com

パイプによるRワークフローのほとんどのdata.frame変数名に接頭辞または接尾辞を追加する

Data.frameのほとんどの変数名に接尾辞または接頭辞を追加したいのですが、通常はすべてが何らかの方法で変換された後、結合を実行する前に行います。配管を壊さずにこれを行う方法はありません。

たとえば、次のデータの場合:

_library(dplyr)
set.seed(1)
dat14 <- data.frame(ID = 1:10, speed = runif(10), power = rpois(10, 1),
                    force = rexp(10), class = rep(c("a", "b"),5))
_

この結果を取得したい(変数名に注意):

_  class speed_mean_2014 power_mean_2014 force_mean_2014
1     a       0.5572500             0.8       0.5519802
2     b       0.2850798             0.6       1.0888116
_

私の現在のアプローチは:

_means14 <- dat14 %>%
  group_by(class) %>%
  select(-ID) %>%
  summarise_each(funs(mean(.)))  

names(means14)[2:length(names(means14))] <- paste0(names(means14)[2:length(names(means14))], "_mean_2014")
_

私のパイプを分割するその不格好な最後の行の代替はありますか?私はselect()rename()を見てきましたが、通常はすべての名前を変更したいので、各変数名を明示的に指定したくありませんexcept単一の変数この例よりもはるかに広いdata.frameを持つ可能性があります。

この構成された関数を近似する最後のパイプコマンドを想像しています。

_appendname(cols = 2:n, str = "_mean_2014", placement = "suffix")
_

それは私の知る限り存在しません。

16
Sam Firke

関数をrename_atに渡すことができるので、

 means14 <- dat14 %>%
  group_by(class) %>%
  select(-ID) %>%
  summarise_all(funs(mean(.))) %>% 
  rename_at(vars(-class),function(x) paste0(x,"_2014"))
18
andyyy

この質問を投稿してからさらに実験を重ねた結果、setNames関数はdata.frameを返すため、パイピングで機能することがわかりました。

dat14 %>%
  group_by(class) %>%
  select(-ID) %>%
  summarise_each(funs(mean(.))) %>%
  setNames(c(names(.)[1], paste0(names(.)[-1],"_mean_2014"))) 

  class speed_mean_2014 power_mean_2014 force_mean_2014
1     a       0.5572500             0.8       0.5519802
2     b       0.2850798             0.6       1.0888116
5
Sam Firke

これは少し速いですが、完全にあなたが望むものではありません:

_dat14 %>%
  group_by(class) %>%
  select(-ID) %>%
  summarise_each(funs(mean(.))) -> means14 

names(means14)[-1] %<>% paste0("_mean_2014")
_

これを確認する前に%<>%-operatorを使用したことがない場合は、 link をチェックしてください。これは非常に便利なツールです。

このdf$meancolumn %<>% round()などの一部の列の再計算または丸めにも使用できます。これは非常に頻繁に表示され、多くの書き込みを節約するだけです。

4
grrgrrbla

2017年2月の時点で、dplyrコマンドrename_(...)を使用してこれを行うことができます。

この例の場合は、実行できます。

dat14 %>%
  group_by(class) %>%
  select(-ID) %>%
  summarise_each(funs(mean(.))) %>%
  rename_(names(.)[-1], paste0(names(.)[-1],"_mean_2014"))) 

これはset_namesの回答にかなり似ていますが、ティブルでも機能します。

4
nstrayer

これは一歩後戻りですが、関数を同時に複数年に適用するためにデータを再形成することを考えるかもしれません。これにより、整頓された状態が保持されます。異なる年を比較することになる場合は、年を名前に格納するのではなく、年をデータフレーム内の個別の変数にすることは理にかなっています。 summarise_を使用して、mean_yearの動作を取得できるはずです。 http://cran.r-project.org/web/packages/dplyr/vignettes/nse.html を参照してください

library(dplyr)
library(tidyr)
set.seed(1)
dat14 <- data.frame(ID = 1:10, speed = runif(10), power = rpois(10, 1),
                    force = rexp(10), class = rep(c("a", "b"),5))

dat14 %>% 
  gather(variable, value, -ID, -class) %>% 
  mutate(year = 2014) %>% 
  group_by(class, year, variable)%>% 
  summarise(mean = mean(value))`
0
Shorpy

setNames()を使用したSam Firkesソリューションは、パイプが壊れないようにする唯一のソリューションですが、列名にアクセスできないため、tbldplyrオブジェクトでは機能しません。通常のベースRネーミング関数のメソッドによる。 hrbrmstrによる this ソリューションのおかげで、tblオブジェクトを使用してパイプ内で使用できる関数を次に示します。指定された列インデックスに事前定義された接頭辞と接尾辞を追加します。デフォルトはすべての列です。

tbl.renamer <- function(tbl,prefix="x",suffix=NULL,index=seq_along(tbl_vars(tbl))){
  newnames <- tbl_vars(tbl) # Get old variable names
  names(newnames) <- newnames
  names(newnames)[index] <- paste0(prefix,".",newnames,suffix)[index] # create a named vector for .dots
  rename_(tbl,.dots=newnames) # rename the variables
}

使用例(auth_usersビーイングtbl_sqlオブジェクト):

auth_user %>% tbl_vars
tbl.renamer(auth_user) %>% tbl_vars
auth_user %>% tbl.renamer %>% tbl_vars
auth_user %>% tbl.renamer(index = c(1,5)) %>% tbl_vars
0
zerweck