[英]Changing a subset of column names in a list of data frames in R
此問題是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'))
這是使用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
您嘗試的兩個問題:
使用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
這是一種按列索引更改列名稱的方法。
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的更新評論之前我發布了這個答案,他說每個數據框的目標列的索引可能不同。 原帖中沒有提到這一點。 請查看其他人的帖子,因為我的答案僅在列索引一致時才有效。
我的解決方案比其他解決方案更復雜,但事實如此。
主要區別在於它不使用==
而是使用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
使用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
這里通過引用進行更改,因此我們首先進行復制。
注意沒有賦值,它不會更改原始對象。
lst <- purrr::map(lst, ~setNames(.x, c('new', names(.x)[-1])))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.