Reputation: 28149
I know if I have a data frame with more than 1 column, then I can use
colnames(x) <- c("col1","col2")
to rename the columns. How to do this if it's just one column? Meaning a vector or data frame with only one column.
Example:
trSamp <- data.frame(sample(trainer$index, 10000))
head(trSamp )
# sample.trainer.index..10000.
# 1 5907862
# 2 2181266
# 3 7368504
# 4 1949790
# 5 3475174
# 6 6062879
ncol(trSamp)
# [1] 1
class(trSamp)
# [1] "data.frame"
class(trSamp[1])
# [1] "data.frame"
class(trSamp[,1])
# [1] "numeric"
colnames(trSamp)[2] <- "newname2"
# Error in names(x) <- value :
# 'names' attribute [2] must be the same length as the vector [1]
Upvotes: 479
Views: 1428434
Reputation: 47310
We might use dplyr::rename_with()
or dplyr::rename_at()
(though the latter is superseded) :
library(dplyr)
cars %>% rename_with(~"new", speed) %>% head()
cars %>% rename_with(~"new", "speed") %>% head()
cars %>% rename_at("speed",~"new") %>% head()
cars %>% rename_at(vars(speed),~"new") %>% head()
cars %>% rename_at(1,~"new") %>% head()
# new dist
# 1 4 2
# 2 4 10
# 3 7 4
# 4 7 22
# 5 8 16
# 6 9 10
Upvotes: 23
Reputation: 324
This is likely already out there, but I was playing with renaming fields while searching out a solution and tried this on a whim. Worked for my purposes.
Table1$FieldNewName <- Table1$FieldOldName
Table1$FieldOldName <- NULL
Edit begins here....
This works as well.
library(dplyr)
df <- dplyr::rename(df, c("oldColName" = "newColName"))
Upvotes: 10
Reputation: 770
I kept thinking about this and came up with the following function
renamecols <- function(df, oldnames, newnames) {
# _______________________________________
# Defenses ####
stopifnot( exprs = {
is.data.frame(df)
length(oldnames) == length(newnames)
# all(oldnames %in% names(df))
}
)
# ___________________________________________
# Computations ####
df_names <- names(df)
old_position <- which(oldnames %in% df_names)
old_available <- oldnames[old_position]
new_available <- newnames[old_position]
tochange <- vector(length = length(old_available))
for (i in seq_along(old_available)) {
tochange[i] <- which(df_names %in% old_available[i])
}
names(df)[tochange] <- new_available
return(df)
}
You can test it in big datasets and it is relatively fast. Of course, it won't be as fast as data.table::setnames()
, but this is a useful solution for base R work.
The nice thing about this approach is that the new and old names can be in any order and the old names do not even need to be present in the data, they are just ignored. The only requirement is that there is direct correspondence between the old and the new names.
n <- 3
l <- as.list(1:(length(letters)*n))
nn <- expand.grid(l = letters, n = 1:n)
names(l) <- paste0(nn$l, nn$n)
df <- as.data.frame(l)
oldnames <- sample(names(df), floor(length(names(df))/3))
newnames <- paste0("new_", oldnames)
renamecols(df, oldnames, newnames) |>
names()
#> [1] "new_a1" "b1" "new_c1" "d1" "new_e1" "f1" "new_g1" "h1"
#> [9] "i1" "j1" "k1" "new_l1" "new_m1" "n1" "o1" "p1"
#> [17] "new_q1" "r1" "s1" "t1" "u1" "new_v1" "new_w1" "new_x1"
#> [25] "y1" "z1" "new_a2" "b2" "c2" "d2" "e2" "f2"
#> [33] "new_g2" "h2" "new_i2" "new_j2" "k2" "l2" "m2" "n2"
#> [41] "new_o2" "p2" "q2" "new_r2" "s2" "t2" "u2" "new_v2"
#> [49] "w2" "x2" "y2" "z2" "a3" "new_b3" "new_c3" "d3"
#> [57] "new_e3" "f3" "g3" "h3" "new_i3" "j3" "k3" "l3"
#> [65] "m3" "n3" "o3" "p3" "new_q3" "r3" "s3" "new_t3"
#> [73] "new_u3" "new_v3" "new_w3" "x3" "y3" "z3"
Created on 2023-05-04 with reprex v2.0.2
Upvotes: 0
Reputation: 141
Let df be the dataframe you have with col names myDays and temp. If you want to rename "myDays" to "Date",
library(plyr)
rename(df,c("myDays" = "Date"))
or with pipe, you can
dfNew <- df %>%
plyr::rename(c("myDays" = "Date"))
Upvotes: 11
Reputation: 846
We can use rename_with
to rename columns with a function (stringr
functions, for example).
Consider the following data df_1
:
df_1 <- data.frame(
x = replicate(n = 3, expr = rnorm(n = 3, mean = 10, sd = 1)),
y = sample(x = 1:2, size = 10, replace = TRUE)
)
names(df_1)
#[1] "x.1" "x.2" "x.3" "y"
Rename all variables with dplyr::everything()
:
library(tidyverse)
df_1 %>%
rename_with(.data = ., .cols = everything(.),
.fn = str_replace, pattern = '.*',
replacement = str_c('var', seq_along(.), sep = '_')) %>%
names()
#[1] "var_1" "var_2" "var_3" "var_4"
Rename by name particle with some dplyr
verbs (starts_with
, ends_with
, contains
, matches
, ...).
Example with .
(x
variables):
df_1 %>%
rename_with(.data = ., .cols = contains('.'),
.fn = str_replace, pattern = '.*',
replacement = str_c('var', seq_along(.), sep = '_')) %>%
names()
#[1] "var_1" "var_2" "var_3" "y"
Rename by class with many functions of class test, like is.integer
, is.numeric
, is.factor
...
Example with is.integer
(y
):
df_1 %>%
rename_with(.data = ., .cols = is.integer,
.fn = str_replace, pattern = '.*',
replacement = str_c('var', seq_along(.), sep = '_')) %>%
names()
#[1] "x.1" "x.2" "x.3" "var_1"
The warning:
Warning messages: 1: In stri_replace_first_regex(string, pattern, fix_replacement(replacement), : longer object length is not a multiple of shorter object length 2: In names[cols] <- .fn(names[cols], ...) : number of items to replace is not a multiple of replacement length
It is not relevant, as it is just an inconsistency of seq_along(.)
with the replace function.
Upvotes: 0
Reputation: 2859
I found colnames()
argument easier
https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/row%2Bcolnames
select some column from the data frame
df <- data.frame(df[, c( "hhid","b1005", "b1012_imp", "b3004a")])
and rename the selected column in order,
colnames(df) <- c("hhid", "income", "cost", "credit")
check the names and the values to be sure
names(df);head(df)
Upvotes: 1
Reputation: 59
I would simply change a column name to the dataset with the new name I want with the following code: names(dataset)[index_value] <- "new_col_name"
Upvotes: 3
Reputation: 10510
The OP's question has been well and truly answered. However, here's a trick that may be useful in some situations: partial matching of the column name, irrespective of its position in a dataframe:
Partial matching on the name:
d <- data.frame(name1 = NA, Reported.Cases..WHO..2011. = NA, name3 = NA)
## name1 Reported.Cases..WHO..2011. name3
## 1 NA NA NA
names(d)[grepl("Reported", names(d))] <- "name2"
## name1 name2 name3
## 1 NA NA NA
Another example: partial matching on the presence of "punctuation":
d <- data.frame(name1 = NA, Reported.Cases..WHO..2011. = NA, name3 = NA)
## name1 Reported.Cases..WHO..2011. name3
## 1 NA NA NA
names(d)[grepl("[[:punct:]]", names(d))] <- "name2"
## name1 name2 name3
## 1 NA NA NA
These were examples I had to deal with today, I thought might be worth sharing.
Upvotes: 3
Reputation: 21
I would simply add a new column to the data frame with the name I want and get the data for it from the existing column. like this:
dataf$value=dataf$Article1Order
then I remove the old column! like this:
dataf$Article1Order<-NULL
This code might seem silly! But it works perfectly...
Upvotes: 1
Reputation: 865
I think the best way of renaming columns is by using the dplyr package like this:
require(dplyr)
df = rename(df, new_col01 = old_col01, new_col02 = old_col02, ...)
It works the same for renaming one or many columns in any dataset.
Upvotes: 58
Reputation: 34907
You can use the rename.vars
in the gdata
package.
library(gdata)
df <- rename.vars(df, from = "oldname", to = "newname")
This is particularly useful where you have more than one variable name to change or you want to append or pre-pend some text to the variable names, then you can do something like:
df <- rename.vars(df, from = c("old1", "old2", "old3",
to = c("new1", "new2", "new3"))
For an example of appending text to a subset of variables names see: https://stackoverflow.com/a/28870000/180892
Upvotes: 7
Reputation: 8141
This is a generalized way in which you do not have to remember the exact location of the variable:
# df = dataframe
# old.var.name = The name you don't like anymore
# new.var.name = The name you want to get
names(df)[names(df) == 'old.var.name'] <- 'new.var.name'
This code pretty much does the following:
names(df)
looks into all the names in the df
[names(df) == old.var.name]
extracts the variable name you want to check<- 'new.var.name'
assigns the new variable name.Upvotes: 804
Reputation: 920
I like the next style for rename dataframe column names one by one.
colnames(df)[which(colnames(df) == 'old_colname')] <- 'new_colname'
where
which(colnames(df) == 'old_colname')
returns by the index of the specific column.
Upvotes: 14
Reputation: 55350
This is an old question, but it is worth noting that you can now use setnames
from the data.table
package.
library(data.table)
setnames(DF, "oldName", "newName")
# or since the data.frame in question is just one column:
setnames(DF, "newName")
# And for reference's sake, in general (more than once column)
nms <- c("col1.name", "col2.name", etc...)
setnames(DF, nms)
Upvotes: 95
Reputation: 1498
This can also be done using Hadley's plyr
package, and the rename
function.
library(plyr)
df <- data.frame(foo=rnorm(1000))
df <- rename(df,c('foo'='samples'))
You can rename by the name (without knowing the position) and perform multiple renames at once. After doing a merge, for example, you might end up with:
letterid id.x id.y
1 70 2 1
2 116 6 5
3 116 6 4
4 116 6 3
5 766 14 9
6 766 14 13
Which you can then rename in one step using:
letters <- rename(letters,c("id.x" = "source", "id.y" = "target"))
letterid source target
1 70 2 1
2 116 6 5
3 116 6 4
4 116 6 3
5 766 14 9
6 766 14 13
Upvotes: 65
Reputation: 443
You could also try 'upData' from 'Hmisc' package.
library(Hmisc)
trSamp = upData(trSamp, rename=c(sample.trainer.index..10000. = 'newname2'))
Upvotes: 4
Reputation:
If you know that your dataframe has only one column, you can use:
names(trSamp) <- "newname2"
Upvotes: 3
Reputation: 176648
colnames(trSamp)[2] <- "newname2"
attempts to set the second column's name. Your object only has one column, so the command throws an error. This should be sufficient:
colnames(trSamp) <- "newname2"
Upvotes: 449