The following code renames first column in the data set:
require(dplyr)
mtcars %>%
setNames(c("RenamedColumn", names(.)[2:length(names(.))]))
Desired results:
RenamedColumn cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
Would it be possible to arrive at the same result using rename
and column index?
This:
mtcars %>%
rename(1 = "ChangedNameAgain")
will fail:
Error in source("~/.active-rstudio-document", echo = TRUE) :
~/.active-rstudio-document:7:14: unexpected '='
6: mtcars %>%
7: rename(1 =
^
Similarly trying to use rename_
or .[[1]]
as column reference will return an error.
You can rename pandas DataFrame column name by index (position) using rename() method or by assigning column name to df. columns. values[index] .
To rename a column in R you can use the rename() function from dplyr. For example, if you want to rename the column “A” to “B”, again, you can run the following code: rename(dataframe, B = A) .
To change multiple column names by name and by index use rename() function of the dplyr package and to rename by just name use setnames() from data. table . From R base functionality, we have colnames() and names() functions that can be used to rename a data frame column by a single index or name.
colnames() method in R is used to rename and replace the column names of the data frame in R. The columns of the data frame can be renamed by specifying the new column names as a vector. The new name replaces the corresponding old name of the column in the data frame.
A column of a data frame can be changed using the position it is in known as its index. Just by the use of index a column can be renamed. This article discusses all such possible methods.
rename () function from dplyr takes a syntax rename (new_column_name = old_column_name) to change the column from old to a new name. The following example renames the column from id to c1.
Rename Column By Index using colnames () colnames () is the method available in R which is used to rename a single column name present in the data frame. Renaming a single column can be done through the column index. We have to specify the index of the column. In R, indexing starts with 1.
How to Select Columns by Index Using dplyr You can use the following basic syntax in dplyr to select data frame columns by index position: #select columns in specific index positions df %>% select (1, 4, 5) #exclude columns in specific index positions df %>% select (-c (1,2))
As of dplyr
0.7.5
, rlang
0.2.1
, tidyselect
0.2.4
, this simply works:
library(dplyr) rename(mtcars, ChangedNameAgain = 1) # ChangedNameAgain cyl disp hp drat wt qsec vs am gear carb # Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 # Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 # Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 # Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1 # Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2 # ...
Original answer and edits now obsolete:
The logic of rename()
is new_name = old_name
, so ChangedNameAgain = 1
would make more sense than 1 = ChangedNameAgain
.
I would suggest:
mtcars %>% rename_(ChangedNameAgain = names(.)[1]) # ChangedNameAgain cyl disp hp drat wt qsec vs am gear carb # Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 # Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 # Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 # Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1 # Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2 # Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
Edit
I have yet to wrap my head around the new dplyr
programming system based on rlang
, since versions 0.6/0.7 of dplyr
.
The underscore-suffixed version of rename
used in my initial answer is now deprecated, and per @jzadra's comment, it didn't work anyway with syntactically problematic names like "foo bar"
.
Here is my attempt with the new rlang
-based Non Standard Evaluation system. Do not hesitate to tell me what I've done wrong, in the comments:
df <- tibble("foo" = 1:2, "bar baz" = letters[1:2]) # # A tibble: 2 x 2 # foo `bar baz` # <int> <chr> # 1 1 a # 2 2 b
First I try directly with rename()
but unfortunately I've got an error. It seems to be a FIXME
(or is this FIXME unrelated?) in the source code (I'm using dplyr
0.7.4), so it could work in the future:
df %>% rename(qux = !! quo(names(.)[[2]])) # Error: Expressions are currently not supported in `rename()`
(Edit: the error message now (dplyr 0.7.5) reads Error in UseMethod("rename_") : no applicable method for 'rename_' applied to an object of class "function"
)
(Update 2018-06-14: df %>% rename(qux = !! quo(names(.)[[2]]))
now seems to work, still with dplyr 0.7.5, not sure if an underlying package changed).
Here is a workaround with select
that works. It doesn't preserve column order like rename
though:
df %>% select(qux = !! quo(names(.)[[2]]), everything()) # # A tibble: 2 x 2 # qux foo # <chr> <int> # 1 a 1 # 2 b 2
And if we want to put it in a function, we'd have to slightly modify it with :=
to allow unquoting on the left hand side. If we want to be robust to inputs like strings and bare variable names, we have to use the "dark magic" (or so says the vignette) of enquo()
and quo_name()
(honestly I don't fully understand what it does):
rename_col_by_position <- function(df, position, new_name) { new_name <- enquo(new_name) new_name <- quo_name(new_name) select(df, !! new_name := !! quo(names(df)[[position]]), everything()) }
This works with new name as a string:
rename_col_by_position(df, 2, "qux") # # A tibble: 2 x 2 # qux foo # <chr> <int> # 1 a 1 # 2 b 2
This works with new name as a quosure:
rename_col_by_position(df, 2, quo(qux)) # # A tibble: 2 x 2 # qux foo # <chr> <int> # 1 a 1 # 2 b 2
This works with new name as a bare name:
rename_col_by_position(df, 2, qux) # # A tibble: 2 x 2 # qux foo # <chr> <int> # 1 a 1 # 2 b 2
And even this works:
rename_col_by_position(df, 2, `qux quux`) # # A tibble: 2 x 2 # `qux quux` foo # <chr> <int> # 1 a 1 # 2 b 2
Here's a couple of alternative solutions that are arguably easier to read because they are not focused around the .
reference. select
understands column indices, so if you're renaming the first column, you can simply do
mtcars %>% select( RenamedColumn = 1, everything() )
However, the issue with using select
is that it will reorder columns if you're renaming a column in the middle. To get around the issue, you have to pre-select the columns to the left of the one you're renaming:
## This will rename the 7th column without changing column order mtcars %>% select( 1:6, RenamedColumn = 7, everything() )
Another option is to use the new rename_at
, which also understand column indices:
## This will also rename the 7th column without changing the order ## Credit for simplifying the second argument: Moody_Mudskipper mtcars %>% rename_at( 7, ~"RenamedColumn" )
The ~
is needed because rename_at
is quite flexible and can accept functions as its second argument. For example, mtcars %>% rename_at( c(2,4), toupper )
will make the names of the second and fourth columns uppercase.
dplyr
has superceded rename_at()
with rename_with()
. You can rename a column by index like this:
library(tidyverse)
mtcars %>%
rename_with(.cols = 1, ~"renamed_column")
#> renamed_column cyl disp hp drat wt qsec vs am gear
#> Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4
#> Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4
#> Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4
#> Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3
#> Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3
#> ...
Be sure to include the tilde (~
)* before the new column name.
Also note that if you introduce the glue
package, you can modify existing column names like this:
library(glue)
mtcars %>%
rename_with(.cols = 1, ~glue::glue("renamed_{.}"))
#> renamed_mpg cyl disp hp drat wt qsec vs am gear carb
#> Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
#> Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
#> Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
#> Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
#> Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
#> ...
Applying the above approach to multiple columns is just a matter of passing in the column index number range using a colon (:
) or multiple indices in a vector using c()
; here's a combination of both:
mtcars %>%
rename_with(.cols = c(1:3, 5), ~glue::glue("renamed_{.}"))
#> renamed_mpg renamed_cyl renamed_disp hp renamed_drat wt
#> Mazda RX4 21.0 6 160.0 110 3.90 2.620
#> Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875
#> Datsun 710 22.8 4 108.0 93 3.85 2.320
#> Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215
#> Hornet Sportabout 18.7 8 360.0 175 3.15 3.440
#> ...
And keep in mind that since the .
represents the current column name, you can apply string modification functions to it like this:
mtcars %>%
rename_with(.cols = c(1:3),
~glue::glue("renamed_{str_replace(.,'mpg','miles_per_gallon')}"))
#> renamed_miles_per_gallon renamed_cyl renamed_disp hp
#> Mazda RX4 21.0 6 160.0 110
#> Mazda RX4 Wag 21.0 6 160.0 110
#> Datsun 710 22.8 4 108.0 93
#> Hornet 4 Drive 21.4 6 258.0 110
#> Hornet Sportabout 18.7 8 360.0 175
#> ...
*You can learn more about the ~
and .
NSE function shorthand here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With