Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing a subset of column names in a list of data frames in R

This question is an extension of Changing Column Names in a List of Data Frames in R.

That post addresses changing names of all columns of a data.frame.

But how do you change the names of only a selected number of columns?

Example:

I want to change the name of the first column only in each data.frame in my list:

dat <- data.frame(Foo = 1:5,Bar = 1:5)
lst <- list(dat,dat)

print(lst)

[[1]]
  Foo Bar
1   1   1
2   2   2
3   3   3
4   4   4
5   5   5

[[2]]
  Foo Bar
1   1   1
2   2   2
3   3   3
4   4   4
5   5   5

(Failed) Attempts:

lapply(1:2, function(x) names(lst[[x]])[names(lst[[x]]) == 'Foo'] <- 'New')
lapply(1:2, function(x) names(lst[[x]])[names(lst[[x]]) == 'Foo'])  <- rep('New',2)
lapply(1:2, function(x) setNames(lst[[x]][names(lst[[x]]) == 'Foo'],'New'))
like image 299
theforestecologist Avatar asked Dec 06 '22 11:12

theforestecologist


2 Answers

Here is one possibility using setNames and gsub:

# Sample data
dat <- data.frame(Foo = 1:5,Bar = 1:5)
lst <- list(dat,dat[, 2:1])

# Replace Foo with FooFoo
lst <- lapply(lst, function(x) setNames(x, gsub("^Foo$", "FooFoo", names(x))) )
#[[1]]
#  FooFoo Bar
#1      1   1
#2      2   2
#3      3   3
#4      4   4
#5      5   5
#
#[[2]]
#  Bar FooFoo
#1   1      1
#2   2      2
#3   3      3
#4   4      4
#5   5      5
like image 118
Maurits Evers Avatar answered May 20 '23 10:05

Maurits Evers


Two problems with your attempts:

  1. It's weird to use lapply(1:2, ...) instead of lapply(lst, ...). This makes your anonymous function more awkward.

  2. Your anonymous function doesn't return the data frame. The last line of a function is returned (in absence of a return() statement). In your first attempt, the value of the last line is just the value assigned, "new" - we need to return the whole data frame with the modified name.

Solution:

lapply(lst, function(x) {names(x)[names(x) == 'Foo'] <- 'New'; x})
# [[1]]
#   New Bar
# 1   1   1
# 2   2   2
# 3   3   3
# 4   4   4
# 5   5   5
# 
# [[2]]
#   New Bar
# 1   1   1
# 2   2   2
# 3   3   3
# 4   4   4
# 5   5   5
like image 24
Gregor Thomas Avatar answered May 20 '23 10:05

Gregor Thomas