此问题是Changing Column Names in a List of Data Frames in R的扩展名。
该帖子解决了更改data.frame的所有列的名称的问题。
但是,如何仅更改选定数量的列的名称?
示例:
我想仅在列表中的每个data.frame中更改第一列的名称:
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
(失败)尝试:
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'))
答案 0 :(得分:5)
以下是使用setNames
和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
答案 1 :(得分:4)
您尝试的两个问题:
使用lapply(1:2, ...)
代替lapply(lst, ...)
很奇怪。这使你的匿名功能更加尴尬。
您的匿名函数不会return
数据框。返回函数的最后一行(没有return()
语句)。在您第一次尝试时,最后一行的值只是指定的值"new"
- 我们需要使用修改后的名称返回整个数据框。
解决方案:
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
答案 2 :(得分:1)
以下是按列索引更改列名称的方法。
lapply(lst, function(x, pos = 1, newname = "New"){
# x: data frame, pos: column index, newname: new name of the column
column <- names(x)
column[pos] <- newname
names(x) <- column
return(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
我在发布OP的更新评论之前发布了这个答案,说明每个数据框的目标列的索引可能不同。原帖中没有提到这一点。请看其他人&#39;发布,因为我的答案仅在列索引一致时才有效。
答案 3 :(得分:1)
我的解决方案比其他解决方案更复杂,但在这里。
主要区别在于==
代替grep
使用ignore.case = TRUE
(带参数lapply(lst, function(DF) {
inx <- grep("^foo$", names(DF), ignore.case = TRUE)
names(DF)[inx] <- "New"
DF
})
#[[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
)。
{{1}}
答案 4 :(得分:1)
使用tidyverse
:
library(tidyverse)
map(lst,rename_at,"Foo",~"New")
# [[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
使用data.table
:
library(data.table)
lst2 <- copy(lst)
lapply(lst2,setnames,"Foo","New")
# [[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
此处通过引用进行更改,因此我们先制作副本。
答案 5 :(得分:0)
注意没有赋值,它不会更改原始对象。
lst <- purrr::map(lst, ~setNames(.x, c('new', names(.x)[-1])))