web-dev-qa-db-ja.com

R dplyr:文字列関数を使用して変数の名前を変更する

(多少関連する質問: dplyrの名前変更機能に新しい列名を文字列として入力

dplyrチェーン(%>%)の途中で、複数の列名を古い名前の関数に置き換えたい(tolowerまたはgsubを使用して、等。)

library(tidyr); library(dplyr)
data(iris)
# This is what I want to do, but I'd like to use dplyr syntax
names(iris) <- tolower( gsub("\\.", "_", names(iris) ) )
glimpse(iris, 60)
# Observations: 150
# Variables:
#   $ sepal_length (dbl) 5.1, 4.9, 4.7, 4.6, 5.0, 5.4, 4.6,...
#   $ sepal_width  (dbl) 3.5, 3.0, 3.2, 3.1, 3.6, 3.9, 3.4,...
#   $ petal_length (dbl) 1.4, 1.4, 1.3, 1.5, 1.4, 1.7, 1.4,...
#   $ petal_width  (dbl) 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3,...
#   $ species      (fctr) setosa, setosa, setosa, setosa, s...

# the rest of the chain:
iris %>% gather(measurement, value, -species) %>%
  group_by(species,measurement) %>%
  summarise(avg_value = mean(value)) 

?renameは引数replacenamed character vector, with new names as values, and old names as names.として受け取ります

だから私は試しました:

iris %>% rename(replace=c(names(iris)=tolower( gsub("\\.", "_", names(iris) ) )  ))

しかし、これは(a)Error: unexpected '=' in iris %>% ...を返し、(b)チェーン内の前の操作からのデータフレームを名前で参照する必要があり、実際の使用例ではできませんでした。

iris %>% 
  rename(replace=c(    )) %>% # ideally the fix would go here
  gather(measurement, value, -species) %>%
  group_by(species,measurement) %>%
  summarise(avg_value = mean(value)) # I realize I could mutate down here 
                                     #  instead, once the column names turn into values, 
                                     #  but that's not the point
# ---- Desired output looks like: -------
# Source: local data frame [12 x 3]
# Groups: species
# 
#       species  measurement avg_value
# 1      setosa sepal_length     5.006
# 2      setosa  sepal_width     3.428
# 3      setosa petal_length     1.462
# 4      setosa  petal_width     0.246
# 5  versicolor sepal_length     5.936
# 6  versicolor  sepal_width     2.770
# ... etc ....  
43
C8H10N4O2

plyr::renameではなく、dplyr::renameのドキュメントを見ていると思います。 dplyr::renameを使用して次のようなことを行います。

iris %>% rename_(.dots=setNames(names(.), tolower(gsub("\\.", "_", names(.)))))
36
Matthew Plourde

2017年5月の非常に遅い回答です

すぐに0.6.0になるdplyr 0.5.0.9004の時点で、maggritrパイプ演算子%>%に準拠した列の名前を変更する多くの新しい方法がパッケージに追加されました。

これらの機能は次のとおりです。

  • rename_all
  • rename_if
  • rename_at

これらの関数の使用方法にはさまざまな方法がありますが、stringrパッケージを使用した問題に関連する方法は次のとおりです。

df <- df %>%
  rename_all(
      funs(
        stringr::str_to_lower(.) %>%
        stringr::str_replace_all(., '\\.', '_')
      )
  )

だから、配管を続けてください:)(意図しないしゃれ)。

41

少し厄介なrename構文を回避する方法を次に示します。

myris <- iris %>% setNames(tolower(gsub("\\.","_",names(.))))
23
Frank

この特定の[しかしかなり一般的な]ケースでは、関数は janitor パッケージで既に記述されています:

library(janitor)

iris %>% clean_names()

##   sepal_length sepal_width petal_length petal_width species
## 1          5.1         3.5          1.4         0.2  setosa
## 2          4.9         3.0          1.4         0.2  setosa
## 3          4.7         3.2          1.3         0.2  setosa
## 4          4.6         3.1          1.5         0.2  setosa
## 5          5.0         3.6          1.4         0.2  setosa
## 6          5.4         3.9          1.7         0.4  setosa
## .          ...         ...          ...         ...     ...

一緒に

iris %>% 
    clean_names() %>%
    gather(measurement, value, -species) %>%
    group_by(species,measurement) %>%
    summarise(avg_value = mean(value))

## Source: local data frame [12 x 3]
## Groups: species [?]
## 
##       species  measurement avg_value
##        <fctr>        <chr>     <dbl>
## 1      setosa petal_length     1.462
## 2      setosa  petal_width     0.246
## 3      setosa sepal_length     5.006
## 4      setosa  sepal_width     3.428
## 5  versicolor petal_length     4.260
## 6  versicolor  petal_width     1.326
## 7  versicolor sepal_length     5.936
## 8  versicolor  sepal_width     2.770
## 9   virginica petal_length     5.552
## 10  virginica  petal_width     2.026
## 11  virginica sepal_length     6.588
## 12  virginica  sepal_width     2.974
9
alistaire

Base、stringr、dplyrを使用した雄弁な試み:

編集:library(tidyverse)に3つのライブラリがすべて含まれるようになりました。

library(tidyverse)
library(maggritr) # Though in tidyverse to use %>% pipe you need to call it 
# library(dplyr)
# library(stringr)
# library(maggritr)

names(iris) %<>% # pipes so that changes are apply the changes back
    tolower() %>%
    str_replace_all(".", "_")

これは、パイピングを使用して関数を作成するために行います。

my_read_fun <- function(x) {
    df <- read.csv(x) %>%
    names(df) %<>%
        tolower() %>%
        str_replace_all("_", ".")
    tempdf %<>%
        select(a, b, c, g)
}
7
mtelesha

select()select_all()の両方を使用して、列の名前を変更できます。

特定の列のみの名前を変更する場合は、selectを使用できます。

_iris %>% 
  select(sepal_length = Sepal.Length, sepal_width = Sepal.Width, everything()) %>% 
  head(2)

  sepal_length sepal_width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
_

renameは同じことを行いますが、everything()を含める必要はありません。

_iris %>% 
  rename(sepal_length = Sepal.Length, sepal_width = Sepal.Width) %>% 
  head(2)

  sepal_length sepal_width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
_

select_all()はすべての列で機能し、関数を引数として取ることができます。

_iris %>% 
  select_all(tolower)

iris %>% 
  select_all(~gsub("\\.", "_", .)) 
_

または、2つの組み合わせ:

_iris %>% 
  select_all(~gsub("\\.", "_", tolower(.))) %>% 
  head(2)

  sepal_length sepal_width petal_length petal_width species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
_
2
sbha

自分で正規表現を書きたくない場合は、使用することができます

  • snakecase-pkg これは非常に柔軟性があり、
  • janitor::make_clean_names()いくつかの素敵なデフォルトがあるか
  • janitor::clean_names()は、make_clean_names()と同じですが、データフレームで直接動作します。

パイプライン内で呼び出すのは簡単です。

library(magrittr)
library(snakecase)

iris %>% setNames(to_snake_case(names(.)))
iris %>% tibble::as_tibble(.name_repair = to_snake_case)
iris %>% purrr::set_names(to_snake_case)
iris %>% dplyr::rename_all(to_snake_case)
iris %>% janitor::clean_names()

0
Taz