2015-05-21 16 views
34

Enter new column names as string in dplyr's rename function有點相關的問題)字符串函數重命名變量或gsub等)[R dplyr:</p> <p>在<code>dplyr</code>鏈(<code>%>%</code>),我想用自己的舊名稱的功能來替代多個列名的中間(使用<code>tolower</code>:使用

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取參數 replace作爲 named character vector, with new names as values, and old names as names.

所以,我想:

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

但這(一)返回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 .... 
+7

優雅的做法是:'虹膜%>%\'名稱< - \'(,tolower的(GSUB( 「\\」, 「_」,名稱( ))))'(我只是在開玩笑。) – Frank

回答

33

我想你看的文檔plyr::rename,不dplyr::rename。你會做這樣的事情與dplyr::rename

iris %>% rename_(.dots=setNames(names(.), tolower(gsub("\\.", "_", names(.))))) 
+2

你可以在''後面的外觀中用'.'來代替'iris'。 – Frank

+0

這是非常有用的,爲什麼你必須使用'rename_'而不是'rename'? – Konrad

+0

習慣,因爲我主要是以編程方式使用dplyr –

21

這裏的周圍有些笨拙rename語法的方式:

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

解決方法的另一個依賴項?這越來越深奧。 – Anton

+0

您可以用'setNames'替換'setnames'並將調用放到'data.table'。 –

+0

@MatthewPlourde D'oh,你說得對。謝謝 – Frank

4

我的使用基礎,stringr和dplyr雄辯的嘗試:

編輯:庫(tidyverse)現在包括所有三個庫。

library(tidyverse) 
    # OR 
# 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) 
} 
+0

str_replace_all不在這兩個包中。 Fyi,不需要在答案的文本中包含「編輯」符號;只是讓它成爲可能的最佳答案。通過點擊答案下方的鏈接,人們可以查看編輯歷史記錄。 – Frank

+0

第一個'str_replace_all'函數的時間段應該被轉義'\\'' - 否則所有內容都被替換爲下劃線 – sbha

8

對於這個特定的[但相當普遍]情況下,功能已被寫入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 
26

這是一個很晚回答,2017年5月

dplyr 0.5.0.9004(即將爲0.6.0)開始,許多重新命名列的新方法,符合maggritr管道運營商%>%已被添加到包中。

,這些功能是:

  • rename_all
  • rename_if
  • rename_at

有使用這些功能的許多不同的方式,但是有關您的問題之一,使用stringr包裝如下:

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

等等,繼續與管道:)(沒有雙關語意)。

+8

很高興知道,謝謝。另外值得注意的是,你可以使用'df%<>%foo()'作爲'df <- df %>%foo()的簡寫' – C8H10N4O2

0

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("\\.", "_", .)) 

或組合兩個:

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 
相關問題